无障碍 API 更新
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
背景动机
随着技术进步和移动应用在日常生活中日益重要,开发无障碍应用的需求也变得越来越迫切。
React Native 有限的无障碍 API 一直是开发者的痛点,因此我们对无障碍 API 进行了多项更新,让创建包容性移动应用更加便捷。
现有 API 的问题
问题一:两个相似却不同的属性 - accessibilityComponentType (Android) 和 accessibilityTraits (iOS)
accessibilityComponentType 和 accessibilityTraits 用于告知 Android 的 TalkBack 和 iOS 的 VoiceOver 用户正在交互的 UI 元素类型。这两个属性存在两大问题:
-
功能相同却使用两套不同机制。旧 API 中这两个平台专属属性不仅使用不便,还给开发者带来困惑。iOS 的
accessibilityTraits支持 17 种值,而 Android 的accessibilityComponentType仅支持 4 种值,且多数值不重叠。更麻烦的是输入格式也不同:accessibilityTraits支持数组或单值,而accessibilityComponentType仅接受单值。 -
Android 功能极其有限。旧属性下 TalkBack 只能识别 "button"、"radiobutton_checked" 和 "radiobutton_unchecked" 三种 UI 元素。
问题二:缺失无障碍提示
当无障碍标签无法明确表达操作结果时,无障碍提示能帮助使用 TalkBack 或 VoiceOver 的用户理解操作效果。这些提示可在设置中开关,但 React Native 的旧 API 完全不支持此功能。
问题三:忽略颜色反转
部分视障用户会开启手机颜色反转功能增强对比度。Apple 提供了允许开发者忽略特定视图的 iOS API,确保开启颜色反转时图片视频不变形,但 React Native 此前未支持该 API。
新 API 设计
解决方案一:整合 accessibilityComponentType (Android) 和 accessibilityTraits (iOS)
为解决 accessibilityComponentType 和 accessibilityTraits 之间的混淆问题,我们将其合并为单一属性。这符合逻辑——两者功能本质相同,合并后开发者无需再考虑平台差异。
技术背景
iOS 中,UIAccessibilityTraits 是可设置于任何 NSObject 的属性。通过 JavaScript 传到原生层的 17 种特性会映射到 Objective-C 的 UIAccessibilityTraits 元素。每个特性用长整型表示,多特性通过按位或(OR)组合。
Android 的 AccessibilityComponentType 则是 React Native 自创概念,不直接对应 Android 原生属性。Android 通过无障碍委托处理:每个视图有默认委托,如需定制需创建新委托并覆盖特定方法。当开发者设置 AccessibilityComponentType 时,原生代码会根据传入组件创建新委托。
具体变更
新属性旨在成为两属性的超集。我们决定新属性主要基于现有属性 accessibilityTraits 进行建模,因为 accessibilityTraits 的值要多得多。这些特性的功能将通过修改无障碍委托在 Android 上实现。
accessibilityTraits 在 iOS 支持 17 种值,但新属性未全采纳。因部分特性效果不明确,且许多值实际极少使用。
这些特性值通常体现两种用途:描述 UI 元素角色或状态。观察发现,开发者通常组合一个角色值(如 "button")与状态值(如 "selected" 或 "disabled")。因此我们拆分出两个新属性:accessibilityRole 和 accessibilityState。
accessibilityRole
新属性 accessibilityRole 用于向 TalkBack 或 VoiceOver 说明 UI 元素角色,支持以下值:
-
none -
button -
link -
search -
image -
keyboardkey -
text -
adjustable -
header -
summary -
imagebutton
此属性仅接受单值,因 UI 元素通常不承担多重角色。特例是图片(image)和按钮(button)的组合,故新增了 imagebutton 角色。
accessibilityStates
新属性 accessibilityStates 用于说明 UI 元素状态,接受包含以下一个或多个值的数组:
-
selected -
disabled
解决方案二:添加无障碍提示
我们新增 accessibilityHint 属性,设置后 TalkBack 或 VoiceOver 将向用户朗读提示内容。
accessibilityHint
此属性接受字符串形式的无障碍提示内容。
iOS 中设置该属性会同步原生视图的 AccessibilityHint 属性,当 iPhone 开启无障碍提示时 VoiceOver 将朗读。
Android 的实现是将提示内容追加到无障碍标签末尾。这样做模拟了 iOS 的行为,但缺点是 Android 无法像 iOS 那样在设置中单独关闭提示。
此设计源于无障碍提示通常对应特定操作(如点击),我们希望保持跨平台行为一致。
问题三解决方案
accessibilityIgnoresInvertColors
我们将 Apple 的 AccessibilityIgnoresInvertColors API 暴露给 JavaScript。现在当您有不希望颜色反转的视图(如图片)时,设置此属性为 true 即可避免反转。
使用方式
这些新属性将在 React Native 0.57 版本中提供。
升级指南
若您当前正在使用 accessibilityComponentType 和 accessibilityTraits,可按以下步骤迁移到新属性。
方法一:使用 jscodeshift 工具
简单场景可通过运行 jscodeshift 脚本完成替换。
此脚本可自动替换以下情况:
accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}
为
accessibilityRole= “trait”
该脚本还会移除 AccessibilityComponentType 实例(假设您每次设置 AccessibilityComponentType 时都会同时设置 AccessibilityTraits)。
方法二:手动代码替换
对于 AccessibilityTraits 使用无对应 AccessibilityRole 值的情况,以及将多个特征值传递到 AccessibilityTraits 的情况,需要手动修改。
通常而言,
accessibilityTraits= {[“button”, “selected”]}
需手动替换为
accessibilityRole=“button”
accessibilityStates={[“selected”]}
这些属性已在 Facebook 代码库中实际应用。令人惊喜的是,Facebook 的代码迁移相当简单:jscodeshift 脚本处理了约半数实例,其余手动修改,整个过程仅耗时数小时。
希望新版 API 能为您带来便利!请持续打造无障碍应用!#包容性设计