我有一个动态的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 类。