如何使用旁白确定当前聚焦的 UITableViewCell 的索引路径?



我有一个动态的UITableView。对于每个单元格,我添加一个UIAccessibilityCustomAction。当操作触发时,我需要知道索引路径,以便我可以相应地响应并更新我的模型。

tableView(_:cellForRowAt:)我像这样添加我的UIAccessibilityCustomAction...

cell.accessibilityCustomActions = [
UIAccessibilityCustomAction(
name: "Really Bad Name",
target: self,
selector: #selector(doSomething)
)
]

我试图使用UIAccessibility.focusedElement无济于事...

@objc private func doSomething() {
let focusedCell = UIAccessibility.focusedElement(using: UIAccessibility.AssistiveTechnologyIdentifier.notificationVoiceOver) as! UITableViewCell
// Do something with the cell, like find the indexPath.
}

问题是转换到单元失败。调试器说返回值类型实际上是一个UITableTextAccessibilityElement,我找不到任何信息。

当操作触发时,我需要知道索引路径,以便我可以相应地响应并更新我的模型。

实现目标的最佳方法是使用 UIAccessibilityFocus 非正式协议方法,方法是直接在对象中重写它们(在本例中为表视图单元格类):在触发自定义操作时,您将能够捕获所需的索引路径。

我建议看看这个答案,处理捕获可访问性焦点的变化,如果需要,其中包含带有代码片段的详细解决方案。 😉

示例代码段...

class SomeCell: UITableViewCell
override open func accessibilityElementDidBecomeFocused() {
// Notify view controller however you want (delegation, closure, etc.)
}
}

我最终不得不自己解决这个问题来掩盖苹果的错误。您可能已经解决了这个问题,但这是一个类似于您的第一个建议的选项。

func accessibilityCurrentlySelectedIndexPath() -> IndexPath? {
let focusedElement:Any
if let voiceOverObject = UIAccessibility.focusedElement(using: UIAccessibility.AssistiveTechnologyIdentifier.notificationVoiceOver) {
focusedElement = voiceOverObject
} else if let switchControlObject = UIAccessibility.focusedElement(using: UIAccessibility.AssistiveTechnologyIdentifier.notificationSwitchControl) {
focusedElement = switchControlObject
} else {
return nil
}
let accessibilityScreenFrame:CGRect
if let view = focusedElement as? UIView {
accessibilityScreenFrame = view.accessibilityFrame
} else if let accessibilityElement = focusedElement as? UIAccessibilityElement {
accessibilityScreenFrame = accessibilityElement.accessibilityFrame
} else {
return nil
}

let tableViewPoint = UIApplication.shared.keyWindow!.convert(accessibilityScreenFrame.origin, to: tableView)
return tableView.indexPathForRow(at: tableViewPoint)
}

我们在这里所做的本质上是获取焦点矩形(在屏幕坐标中),然后将其转换回表视图的坐标空间。然后,我们可以向表视图询问包含该点的索引路径。简单而甜蜜,但如果您使用的是多窗口,您可能需要UIApplication.shared.keyWindow!换成更合适的东西。请注意,当我们处理UIAccessibilityElement时,我们会处理您遇到的问题,即元素是UITableTextAccessibilityElement,因为UITableTextAccessibilityElement是一个私有的内部 Apple 类。

最新更新