如何等待UIAccessibility公告播报完成后再将焦点移到指定元素
实现方案
核心思路
系统的无障碍通知默认是异步执行、没有执行顺序依赖的,你可以通过监听公告播报完成的系统通知,在确认目标公告播报结束后再触发焦点移动操作,避免两个通知相互抢占。
实现步骤
- 注册监听
UIAccessibility.announcementDidFinishNotification系统通知,该通知会在无障碍公告播报完成(或被用户中断)时触发。 - 在通知回调中校验播报的内容、执行状态,确认是你需要的目标公告完成后,再发送
layoutChanged通知移动焦点。 - 业务执行完成后移除通知观察者,避免内存泄漏。
代码示例
首先注册观察者,建议在页面初始化/功能触发前执行:
NotificationCenter.default.addObserver( self, selector: #selector(announcementCompleted(_:)), name: UIAccessibility.announcementDidFinishNotification, object: nil )
实现公告完成的回调方法:
@objc private func announcementCompleted(_ notification: Notification) { guard let info = notification.userInfo, // 校验是否为你发送的目标公告内容 let content = info[UIAccessibility.announcementStringValueUserInfoKey] as? String, content == "a very very very long text", // 可选:仅在公告完整播报完成后执行,若需即使中断也移动焦点可删除该行判断 let isSuccess = info[UIAccessibility.announcementWasSuccessfulUserInfoKey] as? Bool, isSuccess else { return } // 公告完成后再移动焦点 UIAccessibility.post(notification: .layoutChanged, argument: headerResult) // 若后续不需要再监听该通知,在此处移除观察者 NotificationCenter.default.removeObserver( self, name: UIAccessibility.announcementDidFinishNotification, object: nil ) }
原有触发代码仅保留公告发送逻辑即可:
UIAccessibility.post(notification: .announcement, argument: "a very very very long text")
注意事项
- 若业务允许多个公告并发,建议给公告内容加唯一标识做区分,避免回调匹配错误
- 若需要不管公告是否被用户中断都要移动焦点,删除回调中
isSuccess的判断逻辑即可
内容的提问来源于stack exchange,提问作者Anamika
相关产品推荐
相关产品推荐

