TechnologiesSwiftUIAccessibility

AccessibilityRotorEntry struct

iOSmacOStvOSwatchOSvisionOSiOS 15.0+✓ renders

A struct representing an entry in an Accessibility Rotor.

How it works

An AccessibilityRotorEntry describes a single destination within a custom accessibility rotor — the gesture-driven menu VoiceOver users invoke to jump directly between related elements on a screen. Each entry pairs an identifier with a human-readable label, telling the rotor which view to move accessibility focus to and what to announce when it lands there. Reach for AccessibilityRotorEntry when you build a custom rotor with accessibilityRotor(_:entries:) and need to enumerate, in order, the specific items VoiceOver should let users navigate between.

  1. Construct an entry with a label and identifier

    AccessibilityRotorEntry is initialized with a display label and an id value, where the label is what VoiceOver speaks as the user cycles the rotor. In the example, AccessibilityRotorEntry("Important note", id: "Important note", in: notes) names the entry and points it at a matching identifier.

  2. Resolve the target with a namespace

    The in: parameter takes a Namespace.ID so the entry can be matched against a view tagged in the same namespace, rather than resolving against a flat ID space. Here the notes namespace, declared with @Namespace var notes, is passed to the entry so SwiftUI knows which scope to search.

  3. Tag the destination view with accessibilityRotorEntryId

    An entry only resolves if some view advertises the same identifier and namespace, which is the job of accessibilityRotorEntryId(_:in:). The Text(item) inside the ForEach calls .accessibilityRotorEntryId(item, in: notes), so the row labeled "Important note" becomes the view that the entry moves focus to.

  4. Collect entries into a custom rotor

    Entries are handed to accessibilityRotor(_:entries:) as an array, defining a named rotor whose stops are exactly those entries, in the order given. The example attaches .accessibilityRotor("Important", entries: [ ... ]) to the VStack, exposing an "Important" rotor that jumps straight to the single matching note.

Try it — Add a second AccessibilityRotorEntry("Last note", id: "Last note", in: notes) to the entries: array and turn on VoiceOver to hear the "Important" rotor now cycle between two stops instead of one.

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.

AccessibilityRotorEntry.swift
struct AccessibilityRotorEntryDemo: View {
    @Namespace var notes
    let items = ["First note", "Important note", "Last note"]

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Notes")
                .font(.headline)
            ForEach(items, id: \.self) { item in
                Text(item)
                    .accessibilityRotorEntryId(item, in: notes)
            }
        }
        .accessibilityRotor("Important", entries: [
            AccessibilityRotorEntry("Important note", id: "Important note", in: notes)
        ])
        .padding()
    }
}
Live preview
Notes First note Important note Last note
Notes First note Important note Last note
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →