我想使用MacOS accessibility feature我的应用程序呈现自己的自定义 UI(即不使用 Cocoa)。为此,我实现了与我绘制的每个小部件关联的子类 NSAccessibilityElement
树。
根 UI 容器托管在外部提供给我的应用程序的 NSView
内(我的应用程序是一个插件)。现在我需要将我的 NSAccessibilityElement
树附加到主机提供的现有 NSView
上。
Apple documentation推荐两种方法来实现这一目标:
- 重新实现父级的
accessibilityChildren
属性以包含自定义元素(例如 Qt 使用此方法)。不幸的是,我自己没有创建父NSView
,它是从外部注入(inject)的。 - 调用
accessibilityAddChildElement
方便方法。但是当我在提供的 NSView 对象上调用它时,我收到一个异常,它不响应此方法。
将 NSAccessibilityElement
树附加到现有 NSView
的正确方法是什么?
最佳答案
所以我最终对 NSView
进行子类化以捕获顶级 NSAccessibilityElement
。重写 - (NSArray*)accessibilityChildren
方法返回捕获的辅助功能元素作为其子元素之一:
@interface AccessibilityRootView : NSView
- (instancetype)initWithAccessibilityElement: (NSAccessibilityElement*)anElement;
@end
@implementation AccessibilityRootView
{
NSAccessibilityElement* element;
}
- (instancetype) initWithAccessibilityElement: (NSAccessibilityElement*)anElement
{
self = [super init];
if (self)
element = anElement;
return self;
}
- (NSArray*) accessibilityChildren
{
NSArray<NSAccessibilityElement*> *children = [super accessibilityChildren];
int numKids = (int)[children count] + 1;
NSMutableArray<NSAccessibilityElement*> *kids = [NSMutableArray<NSAccessibilityElement*> arrayWithCapacity:numKids];
for (id object in children)
[kids addObject:object];
[kids addObject: element];
return NSAccessibilityUnignoredChildren (kids);
}
@end
然后,我将这个大小为零的子类 View 附加到主机提供的父 NSView
:
NSView* hostView = /* host-provided NSView */;
AccessibilityRootView* accessibilityRootView = [[AccessibilityRootView alloc] initWithAccessibilityElement:(NSAccessibilityElement*)topLevelAccessibilityElement];
[hostView addSubview:accessibilityRootView];
[accessibilityRootView release];
此时,我的所有 NSAccessibilityElements
都已附加到位于主机提供的 View 中的零大小 View ,并且 MacOS 可以成功查询这些项目。
此外,每个 NSAccessibilityElement
必须正确实现其
- (NSRect)accessibilityFrame
和
- (id)accessibilityHitTest:(NSPoint)点
以匹配我自定义绘制的 UI 小部件的屏幕位置。
关于macos - 将 NSAccessibilityElement 添加到现有 NSView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63062794/