TechnologiesSwiftUI

AccessibilityFocusState struct

iOSmacOStvOSwatchOSvisionOSiOS 15.0+✓ renders

A property wrapper type that can read and write a value that SwiftUI updates

How it works

AccessibilityFocusState is a property wrapper that lets your view observe and control where an assistive technology, such as VoiceOver or Switch Control, currently places its focus. It is the accessibility counterpart to FocusState: where FocusState tracks the keyboard focus a sighted user sees, AccessibilityFocusState tracks the element an assistive technology is reading or interacting with. Reach for it when you need to move the assistive cursor programmatically, for example to send a screen-reader user to a newly revealed field or to a validation error after a form submission.

  1. Declare the focus binding with @AccessibilityFocusState

    Annotate a stored property with @AccessibilityFocusState to create a binding whose value reflects, and can drive, the accessibility focus. The wrapped value is typically an optional matching a set of identifiers, so SwiftUI can represent the unfocused state as nil. Here @AccessibilityFocusState private var focus: Field? holds an optional Field value identifying which element accessibility focus rests on.

  2. Define a value type to identify focusable elements

    Because the wrapped value compares against discrete cases, an enum makes a natural identifier for each focusable element. The enum Field { case name, email } gives each text field a distinct tag, and the optional Field? lets focus be nil when nothing is focused.

  3. Bind elements with accessibilityFocused(_:equals:)

    Apply the .accessibilityFocused(_:equals:) modifier to each view that should participate, passing the projected binding and the value that view represents. When accessibility focus lands on that element the binding takes on the matching value, and writing that value back moves focus to it. The first TextField uses .accessibilityFocused($focus, equals: .name) and the second uses .accessibilityFocused($focus, equals: .email), tying each field to its Field case through $focus.

  4. Move accessibility focus by assigning to the wrapped value

    To redirect an assistive technology programmatically, assign a new value to the property. SwiftUI then shifts the accessibility cursor to whichever element was bound to that value. The Button("Focus Email") does exactly this with focus = .email, which moves VoiceOver's focus onto the email TextField.

Try it — Change the button action from focus = .email to focus = .name and run with VoiceOver enabled to watch accessibility focus jump to the Name field instead.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

AccessibilityFocusState.swift
struct AccessibilityFocusStateDemo: View {
    enum Field { case name, email }
    @AccessibilityFocusState private var focus: Field?
    @State private var name = ""
    @State private var email = ""

    var body: some View {
        VStack(spacing: 12) {
            TextField("Name", text: $name)
                .accessibilityFocused($focus, equals: .name)
            TextField("Email", text: $email)
                .accessibilityFocused($focus, equals: .email)
            Button("Focus Email") { focus = .email }
        }
        .textFieldStyle(.roundedBorder)
        .padding()
    }
}
Live preview
Name Email Focus Email
Name Email Focus Email
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →