让支持 VoiceOver 成为一种习惯

让支持 VoiceOver 成为一种习惯

事情的起因

前几天我收到一份特别的反馈(部分摘抄):

感谢您开发了如此强大的pin。我们是一群视力障碍用户,使用iOS自带的辅助功能VoiceOver操作您的pin应用。目前pin总体与VoiceOver兼容良好,但仍存在一些比较影响体验的问题,希望可以得到您的修复。主要问题是应用内以及3d touch菜单和今天插件页面都有不少缺少label信息的按钮,导致voiceover用户无法获知到这些按钮的具体作用。需要根据苹果官方的无障碍开发文档(后面会提供)的方法给这些控件加上正确的label信息。具体问题如下:

我非常感谢这位朋友,这份邮件可以说唤醒了我编写软件中一直忽视的问题:Accessibility,世界上有很多这样的朋友,他们其实更需要软件、工具的帮助,来协助他们的工作与生活。然而 Accessibility 的问题却是我在日常开发中常常忽视的,这一点我感到惭愧。

(这是我的一条朋友圈):
感谢这位朋友让我感受到科技的温度,必须尽力支持。 一年前在 QQ 音乐项目的时候,Vector 同学在做 VoiceOver 的支持,那时候还没有特别的感受。 现在觉得科技是暖的,应该给更多不便的人体会到乐趣。

这份邮件让我重新审视这个问题,我仔细地阅读了开发者文档,并且把自己应用里面不能很好被 VoiceOver 读取的部分都做了改善。

无独有偶,关于 Accessibility,近日也发生了一件比较大的事情:如何评价盲人因难辨12306图形验证码状告铁总,一审被驳回? - 法学

信息无障碍 对于很多朋友还是陌生的话题,今天这篇文章就是聊聊这个,当然我也只是一个新手,只能做一点粗浅的介绍。

VoiceOver

VoiceOver 是苹果推出的一项辅助功能,他可以把屏幕上的元素以语音的方式读出,并且配合一些更简单的交互,让读取的焦点可以在整个屏幕之间不断切换。这样视力障碍的朋友也可以正常的使用,VoiceOver 已经在 iOS 上面存在了很多年,并且提供了一套非常方便的 API,让开发者支持 VoiceOver 可以成为举手之劳,我想这就是苹果这家公司伟大的原因。

“It’s the right thing to do” — Accessibility Programming Guide

尝试 VoiceOver 开发

开发完全支持 VoiceOver 的 iOS 应用,首先要知道如何使用 VoiceOver,你可以在 通用 -> 辅助功能 -> VoiceOver 里面找到他并且开启。不过为了测试的方便,我建议开发者可以将 辅助功能快捷键 设置成 VoiceOver 的切换,这样的话你只需要连按三次 Home 键就能开启/关闭 VoiceOver。

打开 VoiceOver 之后,可以尝试 VoiceOver 练习 功能,该功能将会引导你做一些最基本的 VoiceOver 操作。我们在开发中最基本的几个操作通常是:

  • 点击屏幕元素进行选择
  • 双击屏幕进行按下操作
  • 左右滑动屏幕进行元素切换
  • 三指上下滑动进行 ScrollView 的滚动
  • 双指 Z 字形进行 Escape 操作

这几个操作涵盖了大部分的场景,我们将讨论应用如何兼容这些操作。

没有文字的控件

如果一个控件上面有文字,例如 UIButton 上面有 title,在绝大多数情况下你不用做任何事情,这个控件就能被 VoiceOver 读到。但是当你使用了一个纯图片构造的控件时,请务必为其设置 accessibilityLabel,这个属性在 NSObject 上面,用于提示用户的字符串即可。相应的还有 accessibilityHint 用于做更进一步的提示。

所以结论就是,当你使用纯图片的按钮时,请务必记得为其设置 accessibilityLabel。

这一步当然也是可以做 Localization 的,并且也应该这么做。

处理控件嵌套

有时候一个控件里面会套着多个控件,这种时候 VoiceOver 会搞不清楚要怎么聚焦到控件上面,以及怎么提示给用户。所以这个时候你通常要把最底层的控件设置成

self.isAccessibilityElement = NO;

然后分别对他的 subViews 进行 accessibilityLabel 的设置。

处理 drawRect

在自定义的 View 里面我们常常 drawRect,这是 VoiceOver 的灾难,对于 VoiceOver 而言,整个 drawRect 的内容都是不可见的,他没有办法读取到任何内容。当然得益于 iOS API 的设计,我们还是可以让其简单的支持到 VoiceOver。

假设我们 drawRect 在了一个 container 上面,那么我们要做这样几件事情:

@property (nonatomic, strong) NSArray *accessibleElements;

- (BOOL)isAccessibilityElement {
    return NO;
}

- (NSInteger)accessibilityElementCount {
    return self.accessibleElements.count;
}

- (id)accessibilityElementAtIndex:(NSInteger)index {
    return self.accessibleElements[index];
}

- (NSInteger)indexOfAccessibilityElement:(id)element {
    return [self.accessibleElements indexOfObject:element];
}

重写这几个方法可以让这个 container 的 accessible 元素被我们自己指定,也就是上述代码中的 accessibleElements。然后我们可以在 drawRect 里面做点事情了:

- (void)drawRect:(CGRect)rect {

    [super drawRect:rect];

    NSMutableArray *elements = [NSMutableArray array];

    for (int i=0; i<3; ++i) {
        UIAccessibilityElement *element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
        element.accessibilityLabel = @"hello";
        element.accessibilityFrame = [self convertRect:rect toView:nil];
        [elements addObject:element];
    }

    self.accessibleElements = elements;
}

以上是一个没有绘制逻辑的例子,代表我们有三个元素将会是 accessibleElement,我们通过设置 UIAccessibilityElement 的 accessibilityLabel 和 accessibilityFrame 就可以自定义一个 VoiceOver 可以访问到的元素,accessibilityFrame 将要转换到屏幕上的坐标。

选择态

有时候我们会碰到一种场景,在十个元素里面,选择了其中三个,这个时候可能我们的 UI 已经发生了变化,我们能看到他是被选中的。

但是 VoiceOver 不一定这么认为,如果他读取不到控件的 selected 的话,读屏的时候其实不知道是否被选中的。所以当控件有 selected 属性的时候请务必更新这个状态,而不仅仅是 UI 上面做出一些变化。如果控件上面没有这个属性,也可以通过手动给 accessibilityLabel 加上 已选定 文案的方式来支持。

Escape

上面提到过,VoiceOver 有一个比较复杂的手势:双指画 Z 字型用于执行 Escape 操作。这个操作的含义是 退出当前的页面,最常见的场景是 Pop 或 Dismiss 一个 ViewController,因为我们的关闭操作往往是在页面左上角,对于 VoiceOver 来说不是很方便。

当用户使用双指在控件上画 Z 的时候,会触发:

- (BOOL)accessibilityPerformEscape {
    return YES;
}

这个时候你可以响应自己想要的退出动作,比如说 Dismiss 或者 Pop。

多交流

有时候我们是很难体会使用 VoiceOver 操作的感受的,虽然我们可以假装这样做,但是在现实生活中可能是不够的,我们可能永远都想象不到那种心理活动。所以可以和愿意进行 VoiceOver 测试的用户多交流,使用 TestFlight 进行测试。只有他们,才是真正最懂 Accessibility 的人。

成为习惯

其实上述的内容可以说一点也不复杂,一旦成为开发中的习惯,支持他们将会是轻松的一件事情,他既不会影响我们现有的 UI 表现,也不会给开发和测试带来很多的负担。所以我想我们都应该肩负起这个责任,让软件开发中的 Accessibility 成为一项随手操作。

我开发的 Pin 和 小历 都将在接下来的版本中比较好的支持 VoiceOver 操作,这算是一个比较无耻的广告吧,不过我觉得这样的无耻好像也应该。

有朋友邀请了我回答文章一开始链接中的问题,我想这篇文章应该就是我最好的答案了吧。

最后要感谢这位视力障碍的朋友,也要感谢苹果的伟大,在这整个过程中我学到了很多,却不只是技术上的东西。

- EOF -

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值