kittonian
kittonian

Reputation: 1431

SwiftUI Alert and AccessibilityFocusState Not Changing Focus

I have an alert that confirms the deletion of an item prior to it actually being deleted. There are two buttons in this alert (Cancel and Delete). If the user taps Cancel, nothing changes, and if the user taps Delete the item is deleted.

The problem is that for voiceover users, when either button is tapped, the accessibility focus is arbitrarily moving to some other field in the view (it's not always the same one). I am trying to set the accessibility focus state to a specific view depending on which button is engaged, but the only way I've been able to get this to work is by using an onDisappear modifier on the alert. The issue with that solution is voiceover starts speaking the title of some other field and then the accessibility focus state changes to what I have set, instead of it changing immediately so as not to confuse the user.

I understand that since the alert is a modal the main view must become active again once the modal disappears, but there must be a way to ensure the accessibility focus state is changed properly without confusing the user by it jumping to another field first.

Here's some code to explain:

struct MyView: View {

enum AccessFocusValues {
    case section1
    case section2
}

@AccessibilityFocusState var accessFocus: AccessFocusValues?
@State private var showAlert: Bool = false

    var body: some View {

        Text("Section 1")
            .accessibilityFocused($accessFocus, equals: section1)

        Button {
            showAlert = true
        } label: {
            Text("Tap to Delete")
        }
        .alert(
            Text("My Title"),
            isPresented: $showAlert,
            actions: {
            Button("Cancel", role: .cancel) {
                accessFocus = .section1
            }

            Button("Delete", role: .destructive) {
                accessFocus = .section2
            }
        },
        message: {
            Text("My message")
        })

        Text("Section 2")
            .accessibilityFocused($accessFocus, equals: section2)

    }
}

That does nothing to change the accessibility focus state, however if instead I write an onDisappear modifier, the accessibility focus state does change but as I mentioned, only after it starts reading another field's title.

I also tried creating a simple string var and writing an onChange(of: stringVar) modifier, having the alert's button set the value of stringVar. I can print to console just fine but the accessibility focus state never changes. Additionally, I have tried,

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    accessFocus = .section1
}

and it still doesn't work.

Hoping for a solution.

Upvotes: 1

Views: 860

Answers (0)

Related Questions