Swift如何通过辅助功能画外音引擎了解当前关注的对象
我需要知道可访问性焦点引擎当前关注哪个元素。在一个简单的例子中,让我们假设我是带着两个标签来的。我需要知道,例如,在控制台上打印,或者做其他事情,哪个对象当前被聚焦。如果我有一个有很多不同类型子视图的视图,它们是相同的。我认为我应该使用elementFocusedNotification,并且如文档中所述,使用键UIAccessibilityElementFocusedKeyElement。我想我应该在方法中传递对象,但是如何传递呢 在其他人中,我寻找了一些信息,但找不到解决方案来知道当前关注的是哪个元素 在我的cellForRowAt Indexath中: 在单元格中:Swift如何通过辅助功能画外音引擎了解当前关注的对象,swift,notifications,accessibility,nsnotificationcenter,Swift,Notifications,Accessibility,Nsnotificationcenter,我需要知道可访问性焦点引擎当前关注哪个元素。在一个简单的例子中,让我们假设我是带着两个标签来的。我需要知道,例如,在控制台上打印,或者做其他事情,哪个对象当前被聚焦。如果我有一个有很多不同类型子视图的视图,它们是相同的。我认为我应该使用elementFocusedNotification,并且如文档中所述,使用键UIAccessibilityElementFocusedKeyElement。我想我应该在方法中传递对象,但是如何传递呢 在其他人中,我寻找了一些信息,但找不到解决方案来知道当前关注的
override func accessibilityElementDidBecomeFocused() {
NotificationCenter.default.post(
name: NSNotification.Name(rawValue: UIAccessibility.elementFocusedNotification.rawValue),
object: self.subviews.first(where: {$0.isFocused}),
userInfo: ["UIAccessibilityElementFocusedKeyElement": "hello there"]
)
}
在控制器的viewDidLoad中:
NotificationCenter.default.addObserver(
self,
selector: #selector(self.doSomething(_:)),
name: NSNotification.Name(rawValue: UIAccessibility.elementFocusedNotification.rawValue),
object: nil
)
在同一控制器中
@objc func catchNotification(_ notification: Notification) {
//print("subscribed, notification: \(notification)")
if let myNotification1 = notification.userInfo?["UIAccessibilityElementFocusedKeyElement"] {
print("+++", myNotification1)
}
}
这不是对你问题的直接回答,我也不确定这一切是否如我所说的那样有效。因为苹果隐藏了很多关于易访问性引擎工作原理的细节,但仍然可以从一个完全不同的角度帮助解决您的问题,而且您不需要知道当前的焦点是什么 看看苹果自己的一些应用程序。e、 g.设置应用程序。只能访问整个单元格。这些标签不是 解决办法是: 基于标签覆盖单元格的accessibilityLabel,然后将标签的isAccessibilityElement设置为false。有关更多信息,请参见。向下滚动至“增强表视图的可访问性” 只需在必要时手动设置accessibilityLabel,然后将标签的isAccessibilityElement设置为false。显然,如果标签更新,此解决方案将要求您重置它。 如果为accessoryView设置视图或文本,我相信UITableViewCell也会考虑其值。欲了解更多信息,请参阅
注意:tableviewcell的accessibilityLabel将默认为其标签的文本 首先,细胞永远不会聚焦 画外音关注单个可访问性元素,不通知其超级视图。 因此,如果要使用AccessibilityElementDibEcomeFocused,则必须重写UILabel UIAccessibility.element FocusedNotification是由系统发送的,您可能永远不应该自己发布它 回到你的问题上来。 我想你有以下情况: 无论何时VO焦点标签或视图,您都希望通知您的控制器第i个元素已聚焦 我的做法如下:
class MyViewController ... {
private var VOFocusChanged: NSObjectProtocol?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
VOFocusChanged = NotificationCenter.default.addObserver(
forName: UIAccessibility.elementFocusedNotification,
object: nil,
queue: OperationQueue.main
) {
[weak self] (notification: Notification) in
self?.handleVONotification(notification)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// there is no reason to observe changes
// if we know that view is no longer visible
if let VOFocusChanged: NSObjectProtocol = VOFocusChanged {
NotificationCenter.default.removeObserver(VOFocusChanged)
}
}
private func handleVONotification(_ notification: Notification) {
if let focusedView: UIView = notification.userInfo?[
UIAccessibility.focusedElementUserInfoKey
] as? UIView {
if focusedView.isGrandson(of: view) {
if let fView: ViewWithElement = focusedView as? ViewWithElement {
elementsWasFocused(fView.element)
}
}
}
}
private func elementsWasFocused(_ element: T) {
// add your logic here
}
}
extension UIView {
func isGrandson(of view: UIView) -> Bool {
if superview === view {
return true
}
return superview?.isGrandson(of: view) ?? false
}
}
protocol ViewWithElement {
var element: T { get }
}
// Use this instead of label inside UITableViewCell
class MyLabel: UILabel, ViewWithElement {
func display(element: T) {
_element = element
text = ...
accessibilityLabel = ...
}
// MARK: ViewWithElement
private var _element: T!
var element: T { return _element }
}
每个可访问性元素都应该知道显示的是哪个元素
视图控制器捕获每个通知,检查它是否由TableView的子视图发送,如果是,则从中获取元素
代码如下:
class MyViewController ... {
private var VOFocusChanged: NSObjectProtocol?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
VOFocusChanged = NotificationCenter.default.addObserver(
forName: UIAccessibility.elementFocusedNotification,
object: nil,
queue: OperationQueue.main
) {
[weak self] (notification: Notification) in
self?.handleVONotification(notification)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// there is no reason to observe changes
// if we know that view is no longer visible
if let VOFocusChanged: NSObjectProtocol = VOFocusChanged {
NotificationCenter.default.removeObserver(VOFocusChanged)
}
}
private func handleVONotification(_ notification: Notification) {
if let focusedView: UIView = notification.userInfo?[
UIAccessibility.focusedElementUserInfoKey
] as? UIView {
if focusedView.isGrandson(of: view) {
if let fView: ViewWithElement = focusedView as? ViewWithElement {
elementsWasFocused(fView.element)
}
}
}
}
private func elementsWasFocused(_ element: T) {
// add your logic here
}
}
extension UIView {
func isGrandson(of view: UIView) -> Bool {
if superview === view {
return true
}
return superview?.isGrandson(of: view) ?? false
}
}
protocol ViewWithElement {
var element: T { get }
}
// Use this instead of label inside UITableViewCell
class MyLabel: UILabel, ViewWithElement {
func display(element: T) {
_element = element
text = ...
accessibilityLabel = ...
}
// MARK: ViewWithElement
private var _element: T!
var element: T { return _element }
}
你的“在我的手机里”是什么?你忘了写下来,我想你可以观察到重点项目的变化。尝试观察UIAccessibilityVoiceOverStatusIDChangeNotification,然后查看其用户信息中的内容