Programmatically setting accessibility focus broken?

Hello!

I'm trying to improve the accessibility of a UIKit login form in our iOS app. If an error occurs, an error message is shown in a label that is hidden by default. For our VoiceOver users, I want to move the focus to the error message label so that VoiceOver reads out the error message.

I'm trying to achieve this using UIAccessibility.post, but try as I might, it does not work. To better understand the problem, I created a very simple App which shows a button and a label (always visible), and on pressing the button, I post an accessibility notification:

UIAccessibility.post(notification: .layoutChanged, argument: label)

What I expect to happen is for the focus to move from the button to the label. What happens instead is the focus stays with the button and VoiceOver reads out the button's label again. So it seems to process the notification, but ignore the argument.

Am I misunderstanding how accessibility notifications work or is this simply broken at the moment? I am testing this withy my iPhone with the current iOS version 18.2.1

By the way, using the more modern variant leads to the same result:

AccessibilityNotification.LayoutChanged(label).post()

for UIKit app you may need to give the 'post' code a small delay. Mostly due that accessibility tree is being created behind the scenes and it takes some time. Typical pattern would be:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { UIAccessibility.post(notification: .layoutChanged, argument: label) }

This sounds to me like it should work. If you've tried the delay suggestion, I'd be curious of that helps.

Otherwise, please file a bug report using the Feedback Assistant tool. Adding code samples, a screen recording, and logs from the device will help a lot, https://developer.apple.com/bug-reporting/

After you create your report, reply here with the Feedback ID so I can take a look

Programmatically setting accessibility focus broken?
 
 
Q