Why is UIAccessibility.post(notification: .announcement, argument: "arg") not announced in voice over?

This is an admittedly hacky solution, but I was able to prevent the system announcement from pre-empting my own by dispatching to the main thread with a slight delay:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
  UIAccessibility.post(notification: .announcement, argument: "<Your text>")
}

Your problem may happen because the system needs to take over during the field error appears and, in this case, any customed VoiceOver notification is cancelled.

I wrote an answer about problems with queueing multiple VoiceOver notifications that may help you to understand your current situation.

Your notification works with a breakpoint because you're delaying it and the system works during this time : there's no overlap between your notification and the system work.

A simple solution may be to implement a short delay before sending your notification but the delay depends on the speech rate that's why this is only a temporary workaround.

Your retry mechanism is smart and could be improved inside a loop of few retries in case of many system takeovers.


Another work around is to use .screenChanged instead and pass the error label, as:

UIAccessibility.post(notification: .screenChanged, argument: errorLabel)