TechnologiesSwiftUIAccessibility

AccessibilitySystemRotor struct

iOSmacOStvOSwatchOSvisionOSiOS 15.0+✓ renders

Designates a Rotor that replaces one of the automatic, system-provided

How it works

AccessibilitySystemRotor identifies one of the rotors that VoiceOver already knows how to present—headings, links, landmarks, and similar categories that assistive-technology users navigate by swiping through the rotor control. Rather than naming a custom rotor yourself, you pass one of these built-in values to accessibilityRotor(_:entries:) so your own content becomes the destinations VoiceOver offers under a familiar, standard category. Reach for it when your view contains semantically meaningful elements—like section headings—that should plug into a system rotor VoiceOver users expect to find.

  1. Pick a built-in rotor with a type property like .headings

    AccessibilitySystemRotor exposes the system categories as static members, so you select one with leading-dot syntax instead of constructing it. The example chooses .headings, the rotor VoiceOver users open to jump between section titles; other members cover links, landmarks, and more.

  2. Attach it with the accessibilityRotor(_:entries:) modifier

    You connect the rotor to your view hierarchy by passing the AccessibilitySystemRotor value to .accessibilityRotor. Here .accessibilityRotor(.headings) is applied to the VStack, declaring that this container supplies the destinations for the system headings rotor.

  3. Supply destinations with AccessibilityRotorEntry

    The modifier's trailing closure lists the navigable targets as AccessibilityRotorEntry values, each carrying a label and an identifier. The example maps over headings to emit AccessibilityRotorEntry(heading, id: heading), so each title becomes a stop the rotor can move VoiceOver focus to.

  4. Make the content discoverable to the rotor

    Entries should correspond to elements that are meaningful to assistive technology. The example marks each Text(heading) with .accessibilityAddTraits(.isHeader), reinforcing that these are headings so the .headings system rotor and the elements it points at stay consistent.

Try it — Change .accessibilityRotor(.headings) to .accessibilityRotor(.links) and turn on VoiceOver—the same entries now appear under the Links rotor instead of Headings, showing how the AccessibilitySystemRotor value alone decides which standard category your content joins.

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.

AccessibilitySystemRotor.swift
struct AccessibilitySystemRotorDemo: View {
    let headings = ["Introduction", "Methods", "Results"]
    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            ForEach(headings, id: \.self) { heading in
                Text(heading)
                    .font(.headline)
                    .accessibilityAddTraits(.isHeader)
            }
        }
        .accessibilityRotor(.headings) {
            ForEach(headings, id: \.self) { heading in
                AccessibilityRotorEntry(heading, id: heading)
            }
        }
        .padding()
    }
}
Live preview
Introduction Methods Results
Introduction Methods Results
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →