如何为 VoiceOver 排队多个辅助功能通知?

How can I queue multiple accessibility notifications for VoiceOver?

这是我通知系统读出我的元素的方式:

UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, cell)

问题是当我发送多个通知时,已经阅读的通知被打断了!我希望能够排队...

我在这里的另一个问题中也发现我应该使用属性字符串:

attributedString.addAttribute(NSAttributedStringKey(
    rawValue: UIAccessibilitySpeechAttributeQueueAnnouncement), 
    value: true, 
    range: range!.nsRange)

我在这里错过了什么?

UIAccessibilityAnnouncementNotification 应该在应用需要向用户发出临时通知时使用。它可能不是为重复调用而设计的。

如果确实要排队,可能需要post第一次通知,然后等待UIAccessibilityAnnouncementDidFinishNotification被系统post通知,然后就可以post 队列中的下一条消息。

(但我要提醒您:这真的是视障用户所期待的吗?)

What am I missing here?

我做了很多测试,试图理解这种让我发疯的行为。

我的结论是,如果您在 VoiceOver 说出 {label / hint / value} 时发送通知,您的通知将不会被考虑在内:当系统需要发声时可能会有一种抢占焦点元素的属性。

只有在发声结束时,您才可以 post 任意数量的通知,以便根据需要进行分析和解释。

UIAccessibilitySpeechAttributeQueueAnnouncement 键仅在系统不需要接管时对您自己的通知有用。

如果您发送了很多通知,并且例如用户轻弹以聚焦一个新元素,则当系统发出元素的属性时,未发声的通知将被删除。

在这种情况下,如果您捕捉到 UIAccessibilityAnnouncementDidFinish 事件,您将使用 UIAccessibilityAnnouncementKeyWasSuccessful 键作为最后一个发声通知 (UIAccessibilityAnnouncementKeyStringValue) 的错误值...所有以下将被忽略,观察者不提供任何信息。

结论:当出现新的焦点元素或 screen/layout 更改通知时,VoiceOver 不会考虑任何个人通知

How can I queue multiple accessibility notifications for VoiceOver?

根据上面暴露的内容,我建议设置一种重试机制,它仍然会发送您的通知(x 次) 虽然他们在 y 秒后没有完全收到。
这可能是一种更加确定通知被完美接收的棘手方法。

您可以尝试将 https://github.com/spanage/AccessibilityAnnouncer 用于您自己的通知,但请记住,如果用户点击并与屏幕互动,这些通知将被忽略。

Swift 5 这对我有用:

if (UIAccessibility.isVoiceOverRunning) {
     let message: NSAttributedString = NSAttributedString(string: "read me", attributes: [.accessibilitySpeechQueueAnnouncement: true])
     UIAccessibility.post(notification: .announcement, argument: message)
}

关键是将 .accessibilitySpeechQueueAnnouncement 设置为 true。