ios 为视障用户支持 VoiceOver

其实很少用户知道,ios系统其实有一套完整的轻松访问机制,很多盲人或者说视障用户都喜欢使用iphone

所以说,作为一名开发者,我觉得不论是从产品销售面还是作为责任,都应该做好完善的轻松访问支持。

不过好在,得益于苹果严格的开发规范,所以一般只要你的app已经通过审核能够上架,那么基本上 VoiceOver 就已经能够很好的识别你 app 中的大部分内容了,比较通用的,比如 tabView,比如 navigationController,这些通用的框架都已经自动支持了的。现在,我们就一起来看看,如何让你的 app 利用好 VoiceOver 的所有高级功能,这些功能能够让你在一定程度上控制 VoiceOver,让它更好地兼容你的app,让用户体验更佳完美。

主要目标

VoiceOver 除了能够读出屏幕内容外,其实还可以做更多的内容,比如与界面交互,比如内置的魔法轻拍,魔法返回,要让我们自定义的内容支持它,就需要自己去重写对应的方法,还要让我们自己定制的按钮,按照希望的方式来运作——毕竟使用 VoiceOver 的用户是靠听的,所以有时候我们还需要为按钮等加上更多解释,甚至,在一些动作之后,还要让 VoiceOver 读出特定的内容来告知用户都发生了什么,把这些都规范了,那么视障用户也能轻松地使用你开发的 app 了。

VoiceOver 运行状态

要对 VoiceOver 进行支持,那么得先要能发现它的状态——虽然其实大部分情况下你不需要这么做,因为你在对 VoiceOver 做多配置,如果 VoiceOver 不开启的话,就不会有任何影响,但如果你希望检测一下的话,在 UIKit 里有对应的全局函数:

当然,你也可以不用像我这样在封装一层,我是为了自己整体代码看起来更一致罢了。

设定可读

对于一个自定义的控件,你需要手动地来为它指定是否要作为一个 VoiceOver 控件:

控件角色

ios 为控件提供了一些常见的角色可以配置,比如按钮,比如音量键,为你的控件设定合适恰当的控件角色,这有助于 VoiceOver 为你的控件提供对应的额外功能。

举例来说,对于键盘按钮,就要给按钮去掉按钮角色而使用键盘按钮角色,只有这样,用户才能实现用手指在键盘上滑动,然后找到需要的按钮时,松开手指立即执行按下的操作。

当然,其实这些角色可以是多个,我们通过最后的声明可以看到这个角色类型其实就是一个大的整数: public typealias UIAccessibilityTraits = UInt64 所以我们可以这样:

这里我顺便为大家翻译一下声明里的翻译,具体的特性需要大家自己去尝试。

魔法轻拍

这是一个很常用的手势,就是双指在屏幕上双击。比如说在落格输入法中,它用来快速返回第一个候选(当你往后翻了很久的时候)。如果你想监听这个动作,就在对应的 Controller 里重写  accessibilityPerformMagicTap :

返回 true 来告诉系统,VoiceOver 接收了操作,返回 false 来说明跳过,将内容发送给其他接受者。

魔法返回

魔法返回的手势有点难了,但稍微练习一下应该也不是什么难事,总之,在能够返回的地方比如 navigationController 中双指左右来回一下就是执行了一次魔法返回。还是用落格输入法举例子,那么就是在键盘上执行魔法返回来收起键盘:

手动发出提示

那么,怎么才能主动给用户发出内容提示呢?比如“进入表情键盘”?那么你可以这样:

那么VO就会在你调用它发送通知后读出你的内容,所以,记得要做本地化。

同时,值得一提的是,如果你同时发送多条通知,那么后面的通知会把前边的通知给覆盖掉!比如这样:

那么你得到的很可能是“进入表情键盘”或“进入拼音键盘”,其它的两个就丢失了。

还有比如说在落格输入法之前的版本中,一直存在一个bug,那就是VO里无法读出删除的字。这对于视障用户来说是一件很重要的问题,因为如果你不读出来的话他们就不能确定自己删除了啥,那可真是糟糕透了。而且比这还糟糕的是,我自己本地测试是完全正常的!

所以说,一定要注意这个问题,发送通知不需要一定要在主线程(如果你和我一样常用并发的话),但一定要注意间隔,经过分析,最终我才明白,当你在键盘上点击了删除,那么作为一款第三方键盘,我必须调用内置的api来删除,可是这个删除会触发UI改变(因为文字变了对吧?)VoiceOver就会去傻傻地报告光标位置,显然,一般输入错了肯定是最后一个字居多,那么自然bug就成了读“文本底部”。

这时候,只需要比系统的通知慢就好了,(系统通知比你发的要慢一点,所以它老是覆盖我的通知即使我把它放在了删除调用之后),所以,我这样处理了:

总之,慢这么0.1秒对用户来说他们发现不了什么区别,但对于系统来说,那就是有了足够的时间让VO在收到系统的通知后,还来不及读出就被你的通知给覆盖掉了。

手动改变焦点

当用户点了键盘,或者说做了一些操作之后,我们需要让VO自动将焦点移动到上边,典型的情况就是你在点击了键盘按钮后,候选栏会更新新的候选词,这个时候讲焦点移动到第一个候选就会很好用。因为这样的话,用户就可以双击屏幕直接选中它了。所以,我这样做:

第二个实际参数就是要获得焦点的控件引用,这样收到通知后,VO会立即将焦点移动到这个空间上并读出它的内容。

总结

基本上来说,对于 VoiceOver 的测试,你是无法在 xcode 中完成的,它所附带的工具仅仅能够支持最简单的检查,想要完整地测试你的VO支持,你应该把app安装到你的 iphone 上,然后打开VoiceOver,闭上眼睛去亲自使用一番,如果不擅长 VoiceOver 的你都能顺利地使用你的app,那应该就没什么大问题了。

以上这些,就是我把落格输入法做成 ios 平台 VoiceOver 支持最好的中文输入法的人生经验了。😉

发表评论

电子邮件地址不会被公开。 必填项已用*标注