知识共享许可协议本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。本文仅作为个人学习记录使用,欢迎在许可协议范围内转载或使用,请尊重版权并且保留原文链接,谢谢您的理解合作。如果您觉得本站对您能有帮助,您可以使用RSS方式订阅本站,这样您将能在第一时间获取本站信息。

start

好久木有出现了,大家放心cocoa drawing还在长线更新,最近搬家了,从美丽的彩云之南搬到了高端大气上档次的深圳。于是中间好多天都没有开电脑,好多天就都没有接着写了,以前一直OS X的,今天换换口味来次iOS。

最近看了一个感觉可能平时大家用的少的东西——Voice Over~就是碰一下屏幕就会说话的东西,神奇吧(魂淡,你就是尽找些没人耍的东西写么XDDD),嗯嗯,很神奇啊,so为啥说用的少呢-,-毕竟为特殊人群考虑的太少了,不过麻花的两个app做的还不错(ps,图形解锁直接废了XDDDDDDD能说这是bug么?),之前说找几个一直没找到合适的应用来看下别人做的效果,昨天不小心点了麻花的应用发现做的效果确实挺不错的。好,接下来我们看看怎么用起来。

用起Voice Over

平常要是我们用苹果原生的控件的话,那基本上是天生自带Voice Over的,也就是所有的东西都配合的天衣无缝,但是呢,要是某些小按钮啊,神马的,我们没有妥妥的设置好label之类的东西,更甚者用image之类的东西来当按钮的,那就不一定run的好了,那下面我们先讲下怎么处理原生控件的,接着讲下怎么自定义的,再接着讲下一种优化策略,本文一定程度上参考了Accessibility Programming Guide for iOS大家也可以看看这篇Guide了解更多。

对于原生控件

要用起Voice Over其实并不是很复杂的事情,水果公司的UIView实现了一个叫做UIAccessibility的接口,里面定义了一堆堆的方法,期中最重要的,也就是我们在使用Voice Over时候最常的四个属性如下:

  • accessibilityLabel:告诉大家这是什么,比如飞行模式
  • accessibilityTraits:告诉大家这是什么控件,比如按钮
  • accessibilityValue:告诉大家我的值是什么,常用在文本编辑或者可以修改的东西的地方
  • accessibilityHint:告诉大家,这是干啥用的,比如点两下开启飞行模式想飞多远就飞多远

这么一看立马就懂了吧,想要自定义原生控件元素到底说些啥,就改这三样东西就OK了。

对于自定义的UIView里面的东西

好,接下来我要讲个高档的东西了,自己创造一个UIAccessibilityElement,神马意思呢,就是说我的View里面可能有很多东西,但是他们都不是控件,但是我又需要他们的位置点击后能够说话,告诉我们的童鞋们他们到底是谁。接下来我们一步一步的看要干些啥。

S.1 让我们的UIView成为一个UIAccessibilityContainer

神马是UIAccessibilityContainer呢,从名字猜下,那就是装UIAccessibilityElement的容器了。当然成为这个容器也是需要条件的,首先,欲练此功必先自宫XD,这个容器本身不能是UIAccessibilityElement也就是isAccessibilityElement永远为NO

其次,需要实现下面几个方法:

  1. accessibilityElementCount告诉大家,我有多少个UIAccessibilityElement元素
  2. accessibilityElementAtIndex:告诉大家,第几号元素是哪个
  3. indexOfAccessibilityElement:告诉大家,某个元素是第几号

ok,就这么简单,这样就能实现一个容器了,这样当触屏的时候,系统就会问他,这里是啥啊,他要说点啥啊,之类的了,这里具体的做法有点接近TableView的数据源接口就不详细说了。

S.2 创建UIAccessibilityElement到我们的容器里面

这一步其实跟上文的对于原生控件差不多,只是需要调用UIAccessibilityElementinitWithAccessibilityContainer:方法,将告诉我们的元素容器到底是谁。接下来还要设置UIAccessibilityElementaccessibilityFrame属性,告诉系统我们这个元素响应的区域,不过这里要注意accessibilityFrame使用的是窗口的坐标系,大家用的时候要转换一下。

对于在屏幕上会移动的元素,那么需要重写accessibilityFrame的获取方法,每次获取时进行重新转换坐标系,为了方便大家,我把官方例子里面怎么写的也copy过来了:P

1
2
3
4
5
6
7
8
9
10
11
- (CGRect)accessibilityFrame
{
// Make sure to report the correct, converted bounds to accessibility
CGRect screenBounds = CGRectNull;
UIView *view = [self accessibilityContainer];
if ( [view isKindOfClass:[UIView class]] )
{
screenBounds = [[view window] convertRect:accessibilityBounds fromView:view];
}
return screenBounds;
}

上面的accessibilityBounds是新加的一个变量,是一个CGRect用来记录我们的元素在容器的坐标系中的位置和大小。

之后跟原生控件一样,根据应用的实际需求对上面四个属性赋值即可。

S.3 进一步提升体验使用UIAccessibilityAction接口

在完成了前两步后,可以说应用已经是完整的支持了Voice Over了,但是为了提升更高的体验,我们需要实现UIAccessibilityAction接口中定义的更高端的方法,例如点两下会发生什么的accessibilityActivate方法,对UISlider控件提供更好支持的accessibilityIncrementaccessibilityDecrement方法,等等等等等……

调试Voice Over

调试的话大家可以用手机直接调试,这样最直接,当然还有更好的方式是通过iOS模拟器中带的Accessibility Inspector来进行调试,打开后操作和手机打开了Voice Over效果一样,只是不会出声,但是会把UIAccessibilityElement相关信息都显示出来如下图所示:

Accessibility Inspector

一点点建议

真的只有一点点,为了能够做到更好的体验,其实参考了下麻花的和原生的应用,在一个View很复杂或者有很多操作的时候这时候需要考虑一下如何为特殊人群进行考虑:

  • 为复杂的操作提供可替代的方法:iMessage中,选中一条消息后,他会提示你,上下滑动选择操作,这时候上下滑动的话,那么会提示你,这时候点两下就删除信息了,解决了特殊人群无法适应复杂的界面的问题。
  • 优化UIAccessibilityElement的提示信息:复合的一个View,比如聊天窗口,可以让整个窗口成为一个UIAccessibilityElement,这样可以直接让iPhone说“张麻子在十九点三十分说:师爷你给我翻译翻译”,而不是分别点用户,提示张麻子,点内容,提示内容。
  • 广告:那就仁者见仁智者见智了,建议还是屏蔽了,毕竟人家也不一定能看到你的广告并且如果出现误操作的情况的话,那就不好处理了,某些广告基本都是一个窗口遮住了应用程序主界面。。。不屏蔽,那就是作死了XD,不过有更好的处理办法自然也是不辜负了恩泽的,顺便告诉我下XDDDD

说了一点点。。。就这么多了。。。其实最重要的就是需要站在这用户的角度上去思考,Voice Over并不是单纯的让屏幕上的东西变成可以读的东西,而是为了降低特殊人群使用应用的障碍,所以更多的是需要真正的考虑如何让用户Accessibility而不是单纯的Voice。

end

Oh, YEAH!!我又复活了,哈哈,希望不足之处大家多多指出~~~

最后欢迎大家订阅我的微信公众号 Little Code

公众号

  • 公众号主要发一些开发相关的技术文章
  • 谈谈自己对技术的理解,经验
  • 也许会谈谈人生的感悟
  • 本人不是很高产,但是力求保证质量和原创