UITableViewHeaderFooterView未复用时VoiceOver无法正确识别heading属性问题
问题原因
这是UIKit中UITableView的已知Accessibility兼容性问题,首次加载时系统内部会忽略第一个section header的UIAccessibilityTraits.header配置,只有header被复用后才会正确识别该属性。
可行解决方案
方案1:在tableView(_:willDisplayHeaderView:forSection:)代理中设置可访问性属性
不要在自定义header的初始化方法或重写的属性中设置traits,改为在header即将展示到屏幕前的代理方法中赋值,这时候的设置会覆盖系统内部的错误默认值:
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { guard let header = view as? CustomHeaderView else { return } header.isAccessibilityElement = true header.accessibilityTraits = .header header.accessibilityLabel = header.titleLabel.text // 替换为你的header标题属性 }
方案2:在自定义header的didMoveToWindow生命周期中更新属性
在自定义HeaderFooterView类中重写didMoveToWindow方法,当header被添加到视图层级时重新赋值可访问性属性:
class CustomHeaderView: UITableViewHeaderFooterView { // 其他自定义逻辑 override func didMoveToWindow() { super.didMoveToWindow() // 只有当header被添加到可见窗口时才更新属性 guard window != nil else { return } isAccessibilityElement = true accessibilityTraits = .header } }
方案3:首次加载完成后强制刷新可访问性状态
如果上述方案都不生效,可以在tableView首次调用reloadData之后,延迟极短时间发送布局变更通知,触发系统重新扫描所有可访问性元素:
tableView.reloadData() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { UIAccessibility.post(notification: .layoutChanged, argument: nil) }
内容的提问来源于stack exchange,提问作者Osvaldo Alvarez
相关产品推荐
相关产品推荐

