无障碍功能
译注:accessibility 一词常见多种译法:可访问性、无障碍性、辅助功能等等,其中文意思都不太能准确表达其功能的本质——即为残障人士提供便利。本文主要采用“无障碍功能”和“辅助技术/服务”的说法。如果你或你的公司暂时没有资源和精力去服务这些用户,那么你可以跳过本文。但是,译者个人希望借本文档,呼吁有能力有资源的商业公司/组织/个人,重视残障人士使用智能手机的权利
。
iOS 和 Android 都提供了便于残障人士无障碍使用 App 的 API。此外,两个平台都提供了整套的辅助技术,比如都有针对视力受损人士的读屏软件(iOS 的 VoiceOver 和 Android 的 TalkBack)。同样地,在 React Native 中我们也封装了对应的 API,使开发者能够在 App 中集成无障碍功能。
注意:iOS 与 Android 在具体方法上会有所区别,因此 React Native 的实现也会因平台而异。
无障碍功能属性
accessible
设置为true
时表示当前视图是一个“无障碍元素”(accessibility element)。无障碍元素会将其所有子组件视为一整个可以选中的组件。默认情况下,所有可点击的组件(Touchable 系列组件)都是无障碍元素。
在 Android 上,React Native 视图的accessible={true}
属性会被转译为原生视图对应的focusable={true}
属性。
<View accessible={true}>
<Text>text one</Text>
<Text>text two</Text>
</View>
在上面这个例子中,当父视图开启无障碍属性后,我们就无法单独选中'text one'和'text two',而只能选中整个父视图。
accessibilityLabel
当一个视图启用无障碍属性后,最好再加上一个 accessibilityLabel(无障碍标签),这样可以让使用 VoiceOver 的人们清楚地知道自己选中了什么。VoiceOver 会读出选中元素的无障碍标签。
设定accessibilityLabel
属性并赋予一个字符串内容即可在 View、Text 或是 Touchable 中启用无障碍标签:
<TouchableOpacity
accessible={true}
accessibilityLabel="Tap me!"
onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
在上面这段示例代码中,如果不在 TouchableOpacity 上设置无障碍标签,那么其默认值就会是"Press me!"(即 Text 子组件的文本值)。此时无障碍标签是通过自动取所有 Text 子节点的值,然后用空格连起来生成。
accessibilityLabelledBy
Android
引用另一个元素nativeID来构建复杂的表单。
accessibilityLabelledBy
的值应该与相关元素的nativeID
匹配:
<View>
<Text nativeID="formLabel">用于输入字段标签的编辑框</Text>
<TextInput
accessibilityLabel="输入"
accessibilityLabelledBy="formLabel"
/>
</View>
在上面的例子中,当焦点位于 TextInput 上时,屏幕阅读器会提示输入,用于输入字段标签的编辑框
。
accessibilityHint
无障碍提示用于帮助用户理解操作可能导致什么后果,尤其是当这些后果并不能从无障碍标签中清楚地了解时。
要启用无障碍提示只需在需要设置的元素上设置accessibilityHint
属性,并赋予用于解释的文本:
<TouchableOpacity
accessible={true}
accessibilityLabel="返回"
accessibilityHint="返回到上一个页面"
onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>返回</Text>
</View>
</TouchableOpacity>
在上面这个例子里,iOS 的 VoiceOver 会在标签后读取提示,如果用户在设备的VoiceOver设置中启用了提示。有关accessibilityHint指南的更多信息,请阅读iOS开发者文档。
在上面这个例子里,Android 的 Talkback将在标签后读取提示。目前,Android 上无法关闭提示。
accessibilityLanguage
iOS
通过使用 accessibilityLanguage
属性,屏幕阅读器将了解在阅读元素的 标签、值 和 提示 时要使用哪种语言。提供的字符串值必须遵循 BCP 47 规范。
<View
accessible={true}
accessibilityLabel="Pizza"
accessibilityLanguage="it-IT">
<Text>🍕</Text>
</View>
accessibilityIgnoresInvertColors
iOS
反转屏幕颜色是一项辅助功能,它使得 iPhone 和 iPad 对于某些对亮度敏感的人更加舒适,对于某些色盲患者更容易区分,对于视力低下的人来说更容易识别。然而,有时您会查看照片等视图,并不希望其被反转。在这种情况下,您可以将此属性设置为 false,以便这些特定视图不会反转其颜色。
accessibilityLiveRegion
Android
组件发生动态变化时,我们希望 TalkBack 能够提醒用户。这一行为可以通过设置accessibilityLiveRegion
属性来实现。具体值可以设置为none
,polite
以及assertive
:
- none 辅助服务不应该提醒用户当前视图的变化。
- polite 辅助服务应该提醒用户当前视图的变化。
- assertive 辅助服务应该立即打断当前的语音会话,提醒用户当前视图的变化。
<TouchableWithoutFeedback onPress={this._addOne}>
<View style={styles.embedded}>
<Text>Click me</Text>
</View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
Clicked {this.state.count} times
</Text>
上面这个例子中,_addOne 方法会改变 state.count 这个变量。那么只要用户点击了 TouchableWithoutFeedback,TalkBack 就会读出 Text 组件中的值,因为它设置了accessibilityLiveRegion="polite"
属性。
accessibilityRole
accessibilityRole
communicates the purpose of a component to the user of an assistive technology.
accessibilityRole
can be one of the following:
- adjustable 元素具有可调整的特性(比如一个滑块)。
- alert Used when an element contains important text to be presented to the user.
- button 具有按钮特性。
- checkbox Used when an element represents a checkbox which can be checked, unchecked, or have mixed checked state.
- combobox Used when an element represents a combo box, which allows the user to select among several choices.
- header 作为内容区域的头部(比如导航栏的标题)。
- image 具有图片特性。可以和按钮或链接等连用。
- imagebutton Used when the element should be treated as a button and is also an image.
- keyboardkey 元素作为虚拟键盘的一个键使用。
- link 具有链接特性。
- menu Used when the component is a menu of choices.
- menubar Used when a component is a container of multiple menus.
- menuitem Used to represent an item within a menu.
- none 无特性元素。
- progressbar Used to represent a component which indicates progress of a task.
- radio Used to represent a radio button.
- radiogroup Used to represent a group of radio buttons.
- scrollbar Used to represent a scroll bar.
- search 用作搜索框的文本框。
- spinbutton Used to represent a button which opens a list of choices.
- summary 在 App 冷启动(指完全退出后台后再进入)时提供当前的简要总结信息的元素。比如当天气应用冷启动时,显示当前天气情况的元素就会被标记为summary。
- switch Used to represent a switch which can be turned on and off.
- tab Used to represent a tab.
- tablist Used to represent a list of tabs.
- text 具有不可修改的文本的特性。
- timer Used to represent a timer.
- togglebutton Used to represent a toggle button. Should be used with accessibilityState checked to indicate if the button is toggled on or off.
- toolbar Used to represent a tool bar (a container of action buttons or components).
无障碍状态 accessibilityState
Describes the current state of a component to the user of an assistive technology.
accessibilityState
is an object. It contains the following fields:
名称 | 描述 | 类型 | 必需 |
---|---|---|---|
disabled | Indicates whether the element is disabled or not. | boolean | 否 |
selected | Indicates whether a selectable element is currently selected or 否 t. | boolean | 否 |
checked | Indicates the state of a checkable element. This field can either take a boolean or the "mixed" string to represent mixed checkboxes. | boolean or 'mixed' | 否 |
busy | Indicates whether an element is currently busy or 否 t. | boolean | 否 |
expanded | Indicates whether an expandable element is currently expanded or collapsed. | boolean | 否 |
To use, set the accessibilityState
to an object with a specific definition.
无障碍值 accessibilityValue
Represents the current value of a component. It can be a textual description of a component's value, or for range-based components, such as sliders and progress bars, it contains range information (minimum, current, and maximum).
accessibilityValue
is an object. It contains the following fields:
名称 | 描述 | 类型 | 必需 |
---|---|---|---|
min | The minimum value of this component's range. | integer | Required if now is set. |
max | The maximum value of this component's range. | integer | Required if now is set. |
now | The current value of this component's range. | integer | 否 |
text | A textual description of this component's value. Will override min , now , and max if set. | string | 否 |
accessibilityViewIsModal
iOS
A Boolean value indicating whether VoiceOver should ignore the elements within views that are siblings of the receiver.
For example, in a window that contains sibling views A
and B
, setting accessibilityViewIsModal
to true
on view B
causes VoiceOver to ignore the elements in the view A
. On the other hand, if view B
contains a child view C
and you set accessibilityViewIsModal
to true
on view C
, VoiceOver does not ignore the elements in view A
.
accessibilityElementsHidden
iOS
A Boolean value indicating whether the accessibility elements contained within this accessibility element are hidden.
For example, in a window that contains sibling views A
and B
, setting accessibilityElementsHidden
to true
on view B
causes VoiceOver to ignore the elements in the view B
. This is similar to the Android property importantForAccessibility="no-hide-descendants"
.
无障碍功能优先级 importantForAccessibility
Android
如果有两个 UI 组件同时层叠覆盖在父视图之上,那么默认的无障碍功能的焦点位置就可能难以预料。importantForAccessibility
属性解决了这一问题,它可以控制某个视图是否触发无障碍功能事件,以及是否将其报告给辅助服务。具体值可以设置为auto
,yes
,no
和no-hide-descendants