MMLayerAccessibility 0.1.3

MMLayerAccessibility 0.1.3

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
发布上次发布2014年12月

Markus Müller 维护。




  • 作者
  • Markus Mueller

有时您需要在自定义视图中从 CoreAnimation 层构建用户界面。不幸的是,它们不受 NSAccessibility 支持,从而使 UI 对您的残疾用户无用。

所以,我开发了一个解决方案,它通过类别向 CALayer 及其所有子类添加 NSAccessibility 支持,并提供了一个易于使用的基于块的 API

-(void)setReadableAccessibilityAttribute:(NSString*)attribute withBlock:(id(^)(void))handler;

    CATextLayer *layer...
    __weak CATextLayer *weakLayer = layer;

    [layer setReadableAccessibilityAttribute:NSAccessibilityTitleAttribute
                               withBlock:^id{
                                    CATextLayer *strongLayer = weakLayer;
                                    return strongLayer.string;
                                    }];

使用此方法,您可以将一个可访问性属性设置到一个 CALayer,处理程序块必须返回与属性(如 NSString、NSValue、NSArray 等)特定的值(请参阅 Apple 开发者网站上关于 NSAccessibility 文档的 NSAccessibility Documentation)。

-(void)setWritableAccessibilityAttribute:(NSString*)attribute readBlock:(id(^)(void))getter writeBlock:(void(^)(id value))setter;

    CATextLayer *layer = ...*
    [layer setWritableAccessibilityAttribute:NSAccessibilityTitleAttribute readBlock:^id{
        return weakLayer.string;
        } writeBlock:^(NSString *value) {
        weakLayer.string = value;
    }];

此方法将为 CALayer 提供一个可设置的属性。因为每个可设置的属性都需要可读性,您必须提供getter块。

-(void)setParameterizedAccessibilityAttribute:(NSString*)parameterizedAttribute withBlock:(id(^)(id))handler;

    [layer setParameterizedAccessibilityAttribute:NSAccessibilityLineForIndexParameterizedAttribute
                                        withBlock:^id(id param) {
                                            return @0;
                                        }];

在这里,您提供了一个块,当系统 ax-service 请求层参数化可访问性值(如文本字段中的当前光标位置)时将调用此块。

-(void)setAccessibilityAction:(NSString*)actionName withBlock:(void(^)(void))handler

    [layer setAccessibilityAction:NSAccessibilityPressAction
                        withBlock:^{
                            NSLog(@"action pressed");
                        }];

由于处理程序块存储在各个层上,因此当您在这些块中回引用层时,需要小心以避免保留周期。请在块内部始终使用弱self引用,并在块中将它转换回强引用。

有关如何使用库的详细示例,请查看 LayerView 类。

由于库实现了大量的默认 NSAccessibility 属性,您只需提供与您的 UI 相关的特定属性。内置属性如下

NSAccessibilityRoleAttribute
NSAccessibilityParentAttribute
NSAccessibilitySizeAttribute
NSAccessibilityPositionAttribute
NSAccessibilityWindowAttribute
NSAccessibilityTopLevelUIElementAttribute
NSAccessibilityRoleDescriptionAttribute
NSAccessibilityEnabledAttribute
NSAccessibilityFocusedAttribute

NSAccessibilityRoleAttribute 的默认值是 NSAccessibilityUnknownRole,因此您应该提供一个自己的处理程序,返回更具体的角色,例如 NSAccessibilityButtonRole 或 NSAccessibilityTextFieldRole。有关详细信息,请参阅示例项目。

默认情况下,每个没有至少一个用户定义处理程序的层都会被忽略。要为层的大小、位置、父级等提供默认处理程序,当您设置视图的层时,需要在您的自定义 NSView 中调用一个额外的方法

    CALayer *layer = [self createBackgroundLayer];
    [self setAccessiblityEnabledLayer:layer];

然后您只需在您的自定义视图中实现 NSAccessibility 协议的两个占位方法

    -(NSArray*)accessibilityAttributeNames
    {
        static NSMutableArray *attributes = nil;
        if (!attributes) {
            attributes = [[super accessibilityAttributeNames] mutableCopy];
            NSArray *appendedAttributes = @[NSAccessibilityChildrenAttribute];

            for (NSString *attribute in appendedAttributes) {
                if (![attributes containsObject:attributes]) {
                    [attributes addObject:attribute];
                }
            }
        }
        return attributes;
    }

    -(id)accessibilityAttributeValue:(NSString *)attribute
    {
        if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
            return NSAccessibilityUnignoredChildren(@[self.layer]);
        }
        return [super accessibilityAttributeValue:attribute];
    }

请参阅提供的示例中的 LayerView 类。

该库使用 Kiwi 规范进行了全面单元测试。

使用

要运行示例项目;克隆仓库,然后首先从示例目录运行 pod install
然后请确保系统设置中启用了辅助功能,然后启动辅助功能检查器。
Enable AX AX Inspector 您可以在检查器中检查基于CALayer的用户界面。
examine ui

要求

最低要求是Mac OSX 10.7和ARC。

安装

作者

Markus Mueller,

许可证

MMLayerAccessibility在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。