VoiceOver是iOS系统提供给盲人使用iPhone的一个辅助功能,通过语音形式引导盲人使用软件。可以在设置-通用-辅助功能-VoiceOver中开启。Apple的官方文档有详细介绍:here
正常情况下,App是默认支持VoiceOver的。在开启VoiceOver的时候,UILabel和UIButton都可以通过单次点击来播放文字提示。
但是自定义View如果不做处理,在VoiceOver开启时,无法识别和点击。可以通过下面的方式进行处理:
如果自定义View是一个整体,则比较简单,在init方法中添加两行代码就可以了
- (instancetype) init
{
self = [super initWithFrame:CGRectMake(0, 0, 50, 50)];
if(self)
{
self.isAccessibilityElement = YES;//支持VoiceOver
self.accessibilityLabel = @"自定义View";//语音提示的内容
}
return self;
}
如果自定义View里面包含了几个区域,需要在VoiceOver中得到提示,则需要添加下面的代码:
// 当前View只是作为容器,不能支持VoiceOver
-(BOOL)isAccessibilityElement
{
return NO;
}
-(NSArray*)getAccessElement
{
if(_AccessElements)
{
return _AccessElements;
}
_AccessElements = [[NSMutableArray alloc] init];
UIAccessibilityElement *element = [[[UIAccessibilityElement alloc] initWithAccessibilityContainer:self] autorelease];
element.isAccessibilityElement = YES;
element.accessibilityTraits = UIAccessibilityTraitButton;
CGRect frame = CGRectMake(x, y, 50, 50);
element.accessibilityFrame = [self convertRect:frame toView:nil];// 转换为屏幕坐标
element.accessibilityLabel = @"自定义View的子区域";
[_AccessElements addObject:element];
return _AccessElements;
}
- (NSInteger)accessibilityElementCount
{
return [self getAccessElement].count;
}
- (id)accessibilityElementAtIndex:(NSInteger)index
{
return [[self getAccessElement] objectAtIndex:index];
}
- (NSInteger)indexOfAccessibilityElement:(id)element
{
return [[self getAccessElement] indexOfObject:element];
}
其中,accessibilityElementCount,accessibilityElementAtIndex:和indexOfAccessibilityElement:是NSObject的方法,在VoiceOver开启时,系统会自动调用。如果没有开启VoiceOver,那么_AccessElements也不会被初始化。
另外,accessibilityFrame属性还是比较重要的,这里需要使用屏幕坐标。这属性决定了用户点击屏幕哪个区域,会播放对应的语音提示。
最后,如果需要判断VoiceOver是否开启,可以通过UIAccessibilityIsVoiceOverRunning()来判断。另外,可以查看UIKit中的UIAccessibility.h和UIAccessibilityElement.h文件了解对应API。