UICollectionViewCell的accessibilityElementDidBecomeFocused方法仅在VoiceOver启用时触发的问题
UICollectionViewCell的accessibilityElementDidBecomeFocused方法仅在VoiceOver启用时触发的问题
嘿,我来帮你捋清楚这个问题的根源和解决办法!
首先先确认下你的场景:你给UICollectionViewCell重写了accessibilityElementDidBecomeFocused(),同时设置了canBecomeFocused = true和isAccessibilityElement = true,开启系统的「全键盘访问」后,只有同时打开VoiceOver时这个回调才会触发,单独开全键盘访问就没反应对吧?
问题出在哪?
accessibilityElementDidBecomeFocused()是辅助功能框架专属的回调,它只响应VoiceOver这类辅助工具的焦点变化。而全键盘访问下的焦点属于UIKit原生的键盘焦点——当VoiceOver关闭时,辅助功能的焦点机制并没有激活,所以这个回调自然不会被触发。
怎么解决?
要监听纯全键盘访问下的焦点变化,你需要用UIKit原生的焦点更新方法:didUpdateFocus(in:with:)。这个方法不管VoiceOver开不开,只要是通过全键盘导航切换焦点,都会被触发。
给你个代码示例参考:
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { super.didUpdateFocus(in: context, with: coordinator) // 判断当前cell是否刚获得焦点 if context.nextFocusedView == self { // 把你原来在accessibilityElementDidBecomeFocused里的逻辑搬到这里 print("Cell拿到键盘焦点啦") // 如果需要区分是VoiceOver触发的还是纯键盘触发的,可以加个判断 if UIAccessibility.isVoiceOverRunning { // VoiceOver开启时的额外处理 } else { // 仅全键盘访问时的逻辑 } } }
额外小贴士
- 如果你希望两种场景下行为一致,直接把核心逻辑统一放到
didUpdateFocus里就行;如果需要针对辅助功能和纯键盘做不同处理,也可以保留accessibilityElementDidBecomeFocused,同时在didUpdateFocus里处理纯键盘的情况。 - 别忘了确认你的UICollectionView已经开启了焦点支持(默认是开的,但如果有自定义布局,最好检查下
allowsFocus = true)。
备注:内容来源于stack exchange,提问作者Abubakr Dar
相关产品推荐
相关产品推荐

