VoiceOver是一个语音辅助软件,具备屏幕阅读器的功能,因此视障者及其他无法正常使用App的用户都可以通过VoiceOver来进行操作,位置在设置-通用-辅助功能-VoiceOver。
但是VoiceOver并不是万能的,并不能兼容开发者自定义的控件和视图,因此作为开发者,需要通过一些额外的工作让APP可以支持无障碍使用。
参考:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/iPhoneAccessibility/Introduction/Introduction.html
>= iOS 3.0
单指轻点:设置焦点
单指轻点两下:选中操作
三指左右轻扫:翻页(如果是不分page的网页或ScrollView,会自动按照屏幕显示区域分页查看)
单指左右轻扫:设置上一个/下一个元素为焦点
一般来讲VoiceOver的目的是朗读屏幕的信息,那么下面列举的属性很重要,决定了界面元素可不可以朗读,读什么,类型如何etc
苹果推荐设置属性的方式如下图
获取焦点:UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, element);
直接朗读文本:UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, @”something to read aloud”);
界面发生变化后朗读文本: UIAccessibilityPostNotification ( UIAccessibilityScreenChangedNotification , @” 进入一个新的页面了,应该进行新的操作 “ );
一个灰色的蒙版和一个Picker,这时候设置焦点为picker,到这里都没问题。但是单指滑动的时候焦点居然可以投到灰色蒙版的下面去,会焦点选中蒙版下面的内容。这时候要给灰色蒙版层添加isAccessibilityElement=YES,焦点就不会穿透到下面了
一般来说,一个Cell里面的子元素只是用于朗读,那不需要做特别的设置。如果Cell里面有一些需要交互的元素,或者因为一些原因,需要里面每个元素要独立的可设置焦点,那么类似View的处理
这时候点击Cell的朗读规则要类似系统的股票应用,把每个元素的label拼接在一起作为Cell的label,而不是分开每个元素单独朗读,这样读起来连贯,听起来类似“苹果公司,432.39美元,涨幅1.3%”,如下面的代码:
{
}
- (NSString *)accessibilityLabel { NSString *weatherCityLabel = [self.weatherCityaccessibilityLabel]; NSString *weatherTempLabel = [self.weatherTempaccessibilityLabel]; /* Combine the city and temperature information so that VoiceOver users can get the weather information with one gesture. */ return [NSStringstringWithFormat:@"%@, %@", weatherCityLabel, weatherTempLabel]; }
通常情况下,如果想让子元素设置焦点,父视图不设置焦点,只要把父视图的isAccessibilityElement=NO,子元素为YES就好,代码大概这样:
[_testScrollView setIsAccessibilityElement:NO]; [_testView1 setIsAccessibilityElement:YES]; [_testView2 setIsAccessibilityElement:YES]; [_testView3 setIsAccessibilityElement:YES]; [_testView4 setIsAccessibilityElement:YES];
[_testScrollView setIsAccessibilityElement:NO]; [_testView1 setIsAccessibilityElement:YES]; [_testView2 setIsAccessibilityElement:YES]; [_testView3 setIsAccessibilityElement:YES]; [_testView4 setIsAccessibilityElement:YES];
BUT有下面这种情况:
//todo解决一个问题,父视图是UIScrollView,里面有4个subView分别为testView1,testView2,testView3,testView4,ScrollView的isAccessibilityElement为NO,子视图为YES,应该就可以单指滑动切换子视图选择焦点,但实际在项目中,有时候视图的层级会比较复杂,不知道为什么scrollView上面的子元素又不能滑动了,但是用了代理方法后就可以切换,待排查,先用代理方法实现
- (BOOL)isAccessibilityElement { return NO; } - (NSInteger)accessibilityElementCount { //把响应焦点的元素放到itemArray数组中 return [[self itemArray] count]; } - (id)accessibilityElementAtIndex:(NSInteger)index { return [[self itemArray] objectAtIndex:index]; } //这里可以调整单手指滑动元素选中焦点的顺序 - (NSInteger)indexOfAccessibilityElement:(id)element { return [[self itemArray] indexOfObject:element]; }
- (BOOL)isAccessibilityElement { return NO; } - (NSInteger)accessibilityElementCount { //把响应焦点的元素放到itemArray数组中 return [[self itemArray] count]; } - (id)accessibilityElementAtIndex:(NSInteger)index { return [[self itemArray] objectAtIndex:index]; } //这里可以调整单手指滑动元素选中焦点的顺序 - (NSInteger)indexOfAccessibilityElement:(id)element { return [[self itemArray] indexOfObject:element]; }