iosswiftuiaccessibilityvoiceover

SwiftUI Voiceover with TabView - change spoken text


I have a TabView in SwiftUI and would like to change the spoken text. Currently it says for example "Page three of seven", but I would like to have it only speak what is in the subview. Specifically what I indicated in the .accessibilityLabel() of IndividualPageView.

struct TestVOView: View {
    @State private var currentPage: Int = 0

    var body: some View {
        TabView(selection: $currentPage) {
            ForEach(0..<10) { page in
                IndividualPageView(currentPage: page)
            }
        }
        .tabViewStyle(.page)
    }
}

struct IndividualPageView: View {
    let currentPage: Int
    var body: some View {
        Text("This is page \(currentPage)")
            .accessibilityLabel("This is my accessibility label page \(currentPage)")
    }
}

I have attempted to use .accessiblityHidden(true), but that disables the page turn, have attempted to use .accessiblityRemoveTraits(), and several other combinations, but cannot find a solution after searching through what feels like the entire internet. Any solutions are greatly appreciated.


Solution

  • When I run your example on an iPhone 16 simulator running iOS 26.0 and use the Accessibility Inspector to read the page, it does read your accessibility label when the focus for VoiceOver is on the page content. If it is not working for you, you might need to make sure that the inspector is using the simulator as target, see this answer for the steps.

    If I understand correctly, you want it to read the accessibility label for the page content as it is doing already, but you want to turn off the additional description of the current tab that the native TabView is providing. As you said, this is currently reading "page 3 of 10".

    If the native tab description is turned off then it is important that you replace it with your own tab description, as this will be needed by the user to help them navigate.

    So the native tab description can be replaced by applying an .accessibilityValue to the TabView:

    TabView(selection: $currentPage) {
        // ...
    }
    .tabViewStyle(.page)
    .accessibilityValue("My replacement description for tab \(currentPage)") // 👈 here
    

    When the VoiceOver focus is on the page indicator, it first reads the accessibility value description (as above), then it also reads "updates frequently" and "adjustable". I couldn't find a way to turn these off. In particular, applying .accessibilityRemoveTraits(.updatesFrequently) doesn't help. But I would suggest, it is probably better if these announcements are not turned off anyway.