SwiftUI Accessibility

SwiftUI Accessibility

Apple platforms are renowned for their industry-leading accessibility features, allowing users with disabilities to seamlessly interact with devices.

SwiftUI does a massive amount of the heavy lifting automatically. Standard buttons, toggles, and text fields are inherently accessible.

However, for custom UI elements or complex images, you must provide extra context using SwiftUI's accessibility modifiers.


Accessibility Labels

When a visually impaired user uses VoiceOver, the screen reader reads aloud the elements on the screen.

If you have a button containing only an icon, VoiceOver won't know what it does. You must add an .accessibilityLabel.

Adding a Label:

import SwiftUI

struct PlayButton: View { var body: some View { Button(action: { print("Playing...") }) { Image(systemName: "play.fill") .font(.largeTitle) } // VoiceOver will read "Play Movie" instead of trying to guess .accessibilityLabel("Play Movie") } }


Accessibility Hints and Values

Sometimes a label isn't enough. You want to describe what will happen if the user interacts with the element.

You can use .accessibilityHint() to provide this extra context.

If your custom view acts like a slider or a progress bar, you can communicate its current state using .accessibilityValue().

Adding Hints:

struct DeleteButton: View {
    var body: some View {
        Button("Delete") { }
            .foregroundColor(.red)
            .accessibilityLabel("Delete Post")
            .accessibilityHint("Permanently removes this post from your account.")
    }
}

Hiding Decorative Elements

Not everything on the screen needs to be read by VoiceOver.

If you have background shapes, decorative images, or purely visual spacers, having VoiceOver read them will only confuse and frustrate the user.

You can hide elements from the accessibility system using .accessibilityHidden(true).

Hiding Decorative Views:

struct ProfileHeader: View {
    var body: some View {
        HStack {
            // This is just a visual design element
            Circle()
                .fill(Color.gray)
                .frame(width: 50, height: 50)
                .accessibilityHidden(true) 
            Text("Akash's Profile")
        }
    }
}

Exercise

Which modifier replaces the default spoken text for an element when VoiceOver is active?