我使用NSCollectionView
来水平布局自定义视图。每个NSCollectionViewItem
都承载一个自定义NSView
,其作用类似于复选框。这些自定义子视图本身支持可访问性(通过重写所需的可访问性方法,如accessibilityRole
、accessibilityLabel
等(。
然而,我似乎无法将这些自定义视图提升为主要的UI视图,以便直接访问它们。当我使用辅助功能检查器进行检查时,每个集合视图项似乎都是一个Group
,并且似乎没有办法自动按下按钮,例如,因为自定义视图对它不可见。
我尝试在集合视图项上实现NSAccessibilityButton
,但我不知道accessibilityParent()
返回什么-默认情况下,NSCollectionViewItem
似乎返回父集合视图部分,但这是可以访问的,可能不需要子类化NSCollectionView及其布局。
以下也无济于事:
public override var accessibilityFocusedUIElement: Any? {
return self.customView
}
这永远不会被调用。问题是,在使用NSCollectionView
/NSCollectionViewItem
时,如何添加对可访问性的支持?我只是想展示它的一个子视图,这样它就可以被自动售货机或键盘大师等应用程序访问。
不确定这是一个变通方法还是唯一可能的解决方案,但我就是这样让它工作的:
- 创建一个新的辅助功能代理类,该类可以转发与辅助功能相关的查找
- 在`loadView((中将此类设置为
NSCollectionViewItem
的view
- 将呼叫转接到";可访问";子视图
这是我的代理类:
import Foundation
import Cocoa
/// A wrapper view that acts as a proxy for re-directing accessibility-related lookups.
/// This can be useful in a `NSCollectionViewItem`, for example, to re-direct requests to a child view you'd like to suface as the main, accessible view.
public class BKProxyAccessibleButton: NSView {
public var isAccessibilityElementProxy: (()->Bool)? = nil
public var accessibilityFocusedUIElementProxy: (()->Any?)? = nil
public var accessibilityPerformPressProxy: (()->Bool)? = nil
public var accessibilityValueProxy: (()->NSNumber?)? = nil
public var accessibilityHelpProxy: (()->String?)? = nil
public var accessibilityLabelProxy: (()->String?)? = nil
}
// MARK:- Accessibility
extension BKProxyAccessibleButton: NSAccessibilityButton {
open override func accessibilityRole() -> NSAccessibility.Role? {
return .button
}
open override func accessibilityHelp() -> String? {
return accessibilityHelpProxy?()
}
open override func accessibilityLabel() -> String? {
return accessibilityLabelProxy?()
}
open override func accessibilityTitle() -> String? {
return accessibilityLabelProxy?()
}
open override func isAccessibilityElement() -> Bool {
return isAccessibilityElementProxy?() ?? false
}
open override var accessibilityFocusedUIElement: Any? {
return accessibilityFocusedUIElementProxy?()
}
open override func accessibilityPerformPress() -> Bool {
return accessibilityPerformPressProxy?() ?? false
}
@objc public override func accessibilityValue() -> Any? {
return accessibilityValueProxy?()
}
}