返回介绍

iOS 无障碍

发布于 2019-12-27 01:10:52 字数 6290 浏览 1282 评论 0 收藏 0

引子

这篇教程旨在帮助开发者快速上手 Rax iOS 上的无障碍开发。

无障碍,即「accessibility」(常常缩写成「a11y」),是相对有障碍访问而言的,常见的有障碍访问场景有两类。

一种是用户因为生理缺陷,没有能力按正常的交互方式访问,举几个例子:

  • 视障人士看不见或看不清,无法感受手淘上的信息,动效,氛围;
  • 听障人士听不见或听不清,无法听到音乐以及视频的语音部分;
  • 老年人视力和听力的退化。

一种是用户因为客观原因短时间内无法按正常的交互方式访问,比如开车的时候不方便看着屏幕操作。

无障碍的基本目标是使用户接收到产品想要传达的信息,更高的目标则是所有用户接收到的信息是同等的。

据统计,目前每天至少有 4 万以上的用户在访问手淘 iOS 版本(双十一当天达到了 14 万),Android 手淘用户则更多。而由于链路上的无障碍问题,双促实际进入会场(手淘 iOS)浏览的用户在双十二当天也只达到了一千多。这些数字多少说明了无障碍的必要性,探索空间和挑战。

iOS 上的解决方案和 VoiceOver

iOS 本身提供了一系列的 解决方案

比如用户能够借助 Siri(语音助手),通过语音来控制 IOS 完成一些简单的操作以及得到一些反馈,弱视用户可以通过设置对比度,字号来辅助阅读。

大部分功能都可以在「设置」- 「辅助功能」设置。

其中,比较强大的是 VoiceOver 功能(在 iOS 11.2 以上版本中,VoiceOver 有了中文名「旁白」)。

VoiceOver 开启后,操作方式就和原来不一样了,需要通过特定的手势操作。

通过单指单击来访问界面元素,如果元素可访问,元素会获得焦点,元素周围出现黑框,如果正常配置,VoiceOver 会依次读出元素的标签文本,角色(role),提示(hint)。其中,标签文本之后会有一个短暂的停顿,提示之前则会有一个较长的停顿。这是无障碍中最基础也是最需要保证的流程。

当元素是链接或按钮等可交互的角色时,单指双击会触发行为,等同于正常模式下的点击操作。

除了直接点屏幕来访问元素之外,可以通过单指左滑和右滑按顺序遍历元素,通过三指上滑和下滑在列表元素上跨页浏览。

VoiceOver 还提供了转子功能,用户可以拨转子在多个配置中选择,然后通过单指上滑和下滑来调节这个配置。

更多手势参见 这个手册

我们要做的是在 VoiceOver 开启状态下,保证用户操作畅通,提升体验。

常规操作

合理划分焦点

Weex 中的容器类型组件默认无法获取焦点,例如:

  • div
  • a
  • cell

添加 accessible={true} 属性可以使这些组件能够获得焦点,同时子组件也都将无法获得焦点。

对默认可以获得焦点的组件而言,例如

  • text
  • image
  • input
  • switch

添加 aria-hidden={true} 属性来使这些组件无法获得焦点。

对一般的文本内容,例如活动规则说明,用户协议等,我们不需要做额外处理。

对于图片,如果是无意义的氛围图,一般有两种处理方式,添加 accessible={true} 使其对用户不可见,或为了防止大面积的区域无焦点,使图片的容器可以获得焦点。

对点击产生跳转或交互行为的区域,一般遵循 焦点区域最大化个数最小化 原则。举几个划分的例子:

  • 一个焦点
  • 焦点重叠
  • 多个焦点

检查焦点遍历是否正常。

一行多列布局焦点乱序问题

非通栏的布局下,焦点的遍历顺序和焦点的 top 有关。例如下图这个布局,实际编辑顺序为 A1,B1,A2,A3,B2,B3

而下图这个布局,实际编辑顺序为 A1,B1,A3,B3,A2,B2

目前尝试的解决方案是给容器添加属性 groupAccessibilityChildren={true} ,使得系统优先按组进行遍历。为了保证上述例子中的顺序为 A1,A2,A3,B1,B2,B3,需要给三个 A 结点的容器,A2,B2 的容器分别设置属性。但在 list 中是无效的。

元素内容语义化

默认除了 text 组件获得焦点后会读出包裹的文本内容外,大部分组件获得焦点后是无法读出内容的。

目前比较严重的问题是页面上大部分的图片,获得焦点后,仅读出「图片」。

添加 aria-label="语义化内容" 可以自定义内容。先看一个例子。

  • 焦点 1 的内容模板为: ${标题} ${利益点} ${宣言} ,多个信息之间用 空格 分隔
  • 焦点 2 的内容为 直播中 即可

内容编写的原则:

  • 尽可能和包裹的信息对等
  • 多条信息之间用空格号分隔
  • 不用刻意添加补充文案
时刻

24 小时制 的时刻系统会按字符一个个读出,需要转化成 12 小时制 的写法,比如 23:58
要写成 11.58AM

隐藏价格

大促预热时期,价格部分位会展示成「?」,需要转化成用户能够理解的语音内容。鉴于首位也可能被隐藏,故统一转化成「xx 元以内的形式」。

展示不完整的文本

信息会被脱敏,部分字符会展示成「*」,会都成「星星」,需要将对应文本转化成「星号」。

双十二的 1212 文案

文本内容「1212」会直接朗读成「一千两百一十二」,可以设置为「双十二」或「幺二幺二」。

设置正确的角色

常见的角色有:

  • text,让用户知道当前内容是文本
  • img,获取焦点后会在 label 后读出「图像」,让用户知道当前内容是图片
  • link,获取焦点后会在 label 后读出「链接」,让用户知道点击当前内容会触发页面跳转
  • button,获取焦点后会在 label 后读出「按钮」,让用户知道点击当前内容会触发当前页面交互行为

依赖用户的习惯,角色可以提高用户操作的效率,开发者在简单的场景下,不需要刻意补充指导性文案。

追加提示

可以添加 accessibilityHint="提示" 属性来追加一个提示(hint),这个提示内容会在角色之后间隔相对长的一段时间之后读出。

在 VoiceOver 的设置里是可以设置不朗读提示的,请务必将重要信息包含在内容中,提示只作为渐进增强的方案使用。此外,目前在 web 和 Android 场景,没有对应的功能。

VoiceOver Module

除了 Weex 组件上支持的无障碍特性之外,Weex 新增了模块 voice-over ,提供额外的能力。

VoiceOver 的开启/关闭状态

有些场景可能需要在 VoiceOver 开启的时候做特殊处理,可以通过调用 isVoiceOverOn 方法以及监听 WXVoiceOverStatusChanged 事件来获取 VoiceOver 的开启/关闭状态。

例如监控页面在 VoiceOver 开启下的访问量来推算无障碍用户数。

朗读自定义内容

调用 read 方法能够让系统朗读我们需要的内容。

例如常见的 Toast 组件就需要在展示信息的同时,朗读相应内容。

没有标题的页面需要在页面初始化完成之后朗读出页面标题。

使组件获得焦点

focusToElement 方法会尝试使指定元素获得焦点(前提是该组件能够获得焦点)。

常用的场景是为了保证页面初始化结束之后,页面上的第一个结点(一般是页面左上角的第一个组件)能够获得焦点。这个组件往往是导航条上的后退按钮,由于无法获得后退按钮的 ref,此时需要调用 focusToNavigationBack 方法尝试聚焦。

手淘导航条的定制

设置右侧图标的时候指定朗读内容和角色

// navigator.setNavBarRightItem
navigator.setNavBarRightItem({
  'aria-label': '分享',
  'role': 'button',
  icon: 'share',
  fromNative: 'true',
  iconFont: 'true'
  }, (e) => {
    alert('click!');
  });
}
// navigationBar.setRightItem
navigationBar.setRightItem({
  icon: 'https://gw.alicdn.com/tfs/TB1O.XGXOqAXuNjy1XdXXaYcVXa-60-60.png',
  'aria-label': '新',
  'role':'button'
}

hc.setTBHCConfig 导航中部设置指定朗读内容和角色

会场框架支持在导航条中部配置可以跳转的图片,例如在导航条嵌搜索框。需要额外传入 naviCenterAriaLabel 和 naviCenterRole 来指定朗读内容和角色。例如在导航条嵌搜索框场景,可以设置为

{
  "naviCenterAriaLabel": "双十二搜好物",
  "naviCenterRole": "link",
}

Rax 开发

组件开发

组件的无障碍开发很重要,可以大幅减少业务的无障碍开发成本,大幅提高业务无障碍表现。同时也面临巨大挑战,特别是交互复杂的组件,面临的问题如下:

  • 交互方式需要斟酌,缺少具体的标准,必要时需要邀请用户进行调研
  • VoiceOver 手势的局限,转子功能或新的手势对于用户的学习成本都很高

组件开发者需要保证界面组件支持属性透传到容器,目前很多组件无法设置,只能在组件外再包裹一层容器。功能性组件需要考虑无障碍,在必要时预留朗读内容和角色的入参。

退一步,如果组件对无障碍用户过于复杂,可以暂时先屏蔽(不可见或无法获得焦点)。

业务应用开发

业务开发者大部分要做的是透传属性(配置焦点,朗读内容,角色,提示)。需要注意的:

  • 约定数据字段的时候预留朗读内容需要的字段,尤其是很多文字被做进图片素材的场景,例如图片资源位,需要运营额外提供资源描述字段
  • 尽可能使用组件并收敛组件选择,例如目前有多个途径定制手淘导航条(navigator,navigationBar,hc,WindVane 等),修复一个问题需要挨个修复,且修复成本和难度不可控
  • 某些优化点需要权衡额外的开发工作量和收益

写在最后

Weex 和 Rax 团队在 IOS 上的无障碍基础能力已基本完成,下一阶段会重点关注 Rax 组件和 Android。无障碍是一个产品和团队需要共同关注的话题,欢迎大家一起共建,相关疑问和建议可以在钉钉群中进行,也可以前往 aone 反馈。

更多

开启 VoiceOver 测试

从 iOS 11.2 开始,VoiceOver 在中文系统里译为「旁白」。

可以通过以下路径找到 VoiceOver 的开关:「设置」 -> 「通用」 -> 「辅助功能」 -> 「视觉 - VoiceOver」。

也可以调出 Siri(长按 Home 键),说 「VoiceOver」,Siri 会显示入口。

接着说「打开」直接开启

或直接说 「请打开 VoiceOver」开启

还可以说「设置 VoiceOver」直接进入 VoiceOver 的设置界面。

通过辅助功能快捷键快速开启/关闭 VoiceOver

建议通过设置「辅助功能快捷键」的方式便于后续快速开启/关闭,路径为「设置」 -> 「通用」 -> 「辅助功能」 -> 「辅助功能快捷键」。

若只选择了「VoiceOver」,后续连按三次 Home 键则可以快速开启/关闭 VoiceOver。

若选择了多项,连按三次 Home 键会呼出一个菜单

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文