如何使用画外音确定当前聚焦的 UITableViewCell 的索引路径?
How can I determine the index path for the currently focused UITableViewCell using Voice Over?
我有一个动态的 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.
}
问题是投射到单元格失败。调试器说 return 值类型实际上是 UITableTextAccessibilityElement
,我找不到相关信息。
When the action fires, I need to know the index path so I can respond accordingly and update my model.
达到目标的最佳方式是使用UIAccessibilityFocus informal protocol方法,直接在对象中覆盖它们(table 查看单元格 class 在你的情况下):当自定义操作被触发时,你将能够捕获所需的索引路径。
我建议查看 处理捕获可访问性焦点更改,其中包含详细的解决方案和代码片段(如果需要)。
示例片段...
class SomeCell: UITableViewCell
override open func accessibilityElementDidBecomeFocused() {
// Notify view controller however you want (delegation, closure, etc.)
}
}
我最终不得不自己解决这个问题以避开 Apple 错误。您可能已经解决了这个问题,但这是一个类似于您第一个建议的选项。
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)
}
我们在这里所做的实质是获取聚焦的矩形(在屏幕坐标中),然后将其转换回 table 视图的坐标 space。然后我们可以向 table 视图询问包含该点的索引路径。简单而贴心,但如果您使用 multi-window,您可能需要将 UIApplication.shared.keyWindow!
换成更合适的东西。请注意,当我们处理 UIAccessibilityElement
时,我们会处理您遇到的元素是 UITableTextAccessibilityElement
的问题,因为 UITableTextAccessibilityElement
是私有的内部 Apple class.
我有一个动态的 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.
}
问题是投射到单元格失败。调试器说 return 值类型实际上是 UITableTextAccessibilityElement
,我找不到相关信息。
When the action fires, I need to know the index path so I can respond accordingly and update my model.
达到目标的最佳方式是使用UIAccessibilityFocus informal protocol方法,直接在对象中覆盖它们(table 查看单元格 class 在你的情况下):当自定义操作被触发时,你将能够捕获所需的索引路径。
我建议查看
示例片段...
class SomeCell: UITableViewCell
override open func accessibilityElementDidBecomeFocused() {
// Notify view controller however you want (delegation, closure, etc.)
}
}
我最终不得不自己解决这个问题以避开 Apple 错误。您可能已经解决了这个问题,但这是一个类似于您第一个建议的选项。
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)
}
我们在这里所做的实质是获取聚焦的矩形(在屏幕坐标中),然后将其转换回 table 视图的坐标 space。然后我们可以向 table 视图询问包含该点的索引路径。简单而贴心,但如果您使用 multi-window,您可能需要将 UIApplication.shared.keyWindow!
换成更合适的东西。请注意,当我们处理 UIAccessibilityElement
时,我们会处理您遇到的元素是 UITableTextAccessibilityElement
的问题,因为 UITableTextAccessibilityElement
是私有的内部 Apple class.