iOS中的辅助功能(Accessibility) -- 旁白(VoiceOver)

本文旨在系统性的介绍iOS的Accessibility旁白功能,什么是Accessibility?用户如何操作使用?Accessibility相关API如何使用?Accessibility的代码实践、解决实际问题?

一、什么是Accessibility?如何使用?

什么是Accessibility呢?
简单来说,就是无障碍化使用,这里的“无障碍”面向的群体是视障人士。
一般来说,在App的开发过程中,我们都会关注产品的易用性、考虑不同用户的需求。但是,我们的关注点往往在于身体健全的用户,而对于视障人士,其实也是潜在的用户群体,当我们需要服务好这类用户群体时,就需要做好App对于Accessibility的支持了。

对于目前的移动端,无论是Android还是iOS,其实系统已经为我们提供了Accessibility的接口。拿iOS来说,苹果已经在UIKit中集成了UIAccessibility,当我们在使用UI控件时,都可以设置Accessibility相关的属性,进而支持功能。

说了这么多,我们先来看看如何在iPhone上开启Accessibility功能。
进入“设置(Settings)”->"通用(General)"->"辅助功能(Accessibility)"->"旁白(VoiceOver)",开启旁白的开关


截屏2020-12-18 上午11.19.19.png

当我们开启成功后,屏幕上就会出现黑色边框,并且手机会帮助我们读出边框选中的内容。

二、Accessibility模式下的用户操作

如上所述,当我们开启了Accessibility的旁白功能后,整个用户操作的模式也相应的发生了改变,更加的符合视障人士的习惯。同时,我们也可以闭上眼睛,对手机App进行操作,去感受怎样的代码实现对于视障人士更加的友好。
在此,针对这种模式下的手势操作代表的功能做一个简述:
1.单击手势:
黑色边框会移动并聚焦到单击的界面元素上,同时读出当前选中部分所代表的功能、内容。此时的单击手势和正常情况下不同,并不会触发代码层面的功能的响应。
2.双击手势:
如果当前黑色边框聚焦的界面元素是一个Button或者关联了一些点击响应方法等,则此时会触发相应的方法,等同于正常情况下的单击操作。
3.单指滑动:
会将黑色边框移动聚焦到下一个界面元素上(向左滑动会聚焦到上一个元素上)
4.三指滑动:
一般会触发tableview、scrollview等的滑动功能,进而滑动页面
5.回到主屏幕(无home键手机):
手指从底部向上滑动且不离开屏幕,直到感知到震动后,松开手指,就会回到主屏幕

在这里主要描述了使用概率较高的集中操作方式。总之,在这种模式下的手势操作要更加复杂一点,但是对于视障人士更加友好,提升了操作的准确性。

三、代码如何更好的支持Accessibility呢?

如开头所说,iOS已经帮我们在UIKit中集成了Accessibility的一些功能。也就是说,在我们开发完一个项目后,暂未添加任何Accessibility相关代码的情况下,我们的App已经支持了一些旁白功能,能够自动聚焦并且读出Label的内容等。
但是,仅仅是这样还是不够的,对于视障人士来说可用性还是比较差的,所以我们需要通过对Accessibility的一些API进行操作,进而提升易用性。
所有标准的UIKit控件和UIView默认都是支持VoiceOver的,但是我们通常会自定义UI,此时VoiceOver就无法正确的为我们聚焦并读出我们想要的结果,此时就需要对Accessibility的编程接口进行修改来支持无障碍使用。

1、Accessibility常用API介绍:
  • isAccessibilityElement
    一般来说我们在App上能够看到的界面元素都是AccessibilityElement。对于UIKit中的UIButton、UILabel等控件,它们的isAccessibilityElement默认是true,而UIView的isAccessibilityElement默认是false。系统能够自动捕捉并聚焦到AccessibilityElement是true的元素,因此,不需要聚焦到某个元素时将其isAccessibilityElement设置为false即可;需要聚焦则设置为true。

  • accessibilityLabel
    描述内容是什么。一般对于UILabel不需要进行设置,会直接读出label的内容;对于UIButton,若设置了图标的话,可能会直接读出图标的命名,因此需要对这个按钮的功能描述进行设置,例如“返回按钮”。

  • accessibilityHint
    描述详细信息(补充说明等)。一般不需要进行设置,如果读完当前元素的内容(或功能、名称)外,还需要对此进一步解释说明、提示等,则 可以针对此属性进行设置。

  • accessibilityValue
    描述值是多少。比如当前存在加载进度时,需要实时告知用户当前百分比。

  • accessibilityTraits
    描述当前元素的状态、类型等信息。例如,描述当前的元素为一个按钮则设置为“button”;当前元素高亮或已勾选则设置为“selected”,等等。根据当前的需求去设置对应的特征描述。

  • accessibilityFrame
    描述当前聚焦框的区域大小。系统会读出当前聚焦框区域中的内容。

  • UIAccessibility.post()
    通过这个通知方法可以完成我们特殊的一些需求。

    public static func post(notification: UIAccessibility.Notification, argument: Any?)
    

    具体的用法,示例如下:

    //在点击某个按钮后,我们需要将自动聚焦到title上,则可以执行以下代码
    UIAccessibility.post(notification: .layoutChanged, argument: titleLabel)
    //如果在点击某个按钮后并且没有筛选到结果,想要提示“未搜索到结果”,则可以执行以下代码
    UIAccessibility.post(notification: .layoutChanged, argument: “为搜索到结果”)
    

    通知里的第一个参数,具体使用“layoutChanged”、“screenChanged”还是其他,根据当前的需求来看,一般来说这两个足够使用了,至于他俩的区别是啥,可以参考这篇文章

这里只是重点说了常用的一些API及其使用方法,除此之外的系统API有兴趣的可以自行了解,苹果都有详细的注释

2、代码实践,解决实际问题:

1. 常用系统方法的基本使用:

let percent = "25%"
moreButton.accessibilityLabel = "more function"
moreButton.accessibilityTraits = .button
moreButton.accessibilityHint = "Tap to show coupon details"
moreButton.accessibilityValue = percent
//通知的用法上面已经介绍过,这里不再赘述

2. 界面元素聚焦定位的问题:
通常情况下,用户在进行界面操作后,如点击按钮、搜索等等,系统会自动帮我们重新聚焦定位、或者保持不变,但是这种表现达不到我们的预期,所以我们需要重新手动聚焦到特定的元素上。
针对这个问题,可以通过UIAccessibility.post()通知来解决。

//这里的argument传递需要聚焦的UI控件元素上。在某些特定情况下需要修改系统定位的焦点,可通过延时触发的方式执行方法
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
    UIAccessibility.post(notification: .layoutChanged, argument: self.titleLabel)
}

3. 用户进行某个操作后并未触发UI控件,需要对用户进行提示:
在实际开发中,有时存在这样一个场景,用户从上一个页面返回后,会自动刷新当前的页面,但是没有特定的UI元素聚焦能够说明此变更。
针对此问题,可以通过通知来解决。在返回到当前页面时,触发通知,传递需要读出的内容

//这里的argument可以传字符串(提示的内容)。
UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: "当前页面已更新")

4. 自定义UI控件,聚焦定位不准确:
当我们自定义一个UIView,并在上面添加Button、Label等控件,若不进行处理,则聚焦框会分别依次聚焦到Button、Label上。如果需要将这个View当作一个聚焦的整体,则需要将View的isAccessibilityElement属性设置为true;同时添加到View上的标准UI控件则不会被单独聚焦到了,如果有个别依然会被聚焦的则将其isAccessibilityElement设置为false。

5. 增加扩张功能:
例如,我们在针对标题类的内容时,不仅需要读出标题,还需要读出当前的标题是主标题、副标题,或者一级标题、二级标题等等。针对此类需求,可以对View、Label等增加分类方法,根据不同的需求扩展方法,对Accessibility进行设置。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,406评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,976评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,302评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,366评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,372评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,457评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,872评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,521评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,717评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,523评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,590评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,299评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,859评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,883评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,127评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,760评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,290评论 2 342

推荐阅读更多精彩内容