How do Voice Control, Switch Control and keyboard access use your UI, and what do accessibility input labels and focus order change?

24.1.3 · L3 · Interview

Predict first

A button is given three input labels for Voice Control. What does it report?

import UIKit

@MainActor func run() {
    let button = UIButton(type: .system)
    button.setTitle("Share", for: .normal)
    button.accessibilityUserInputLabels = ["Share", "Send", "Post"]
    print(button.accessibilityUserInputLabels ?? [])
}
MainActor.assumeIsolated { run() }
  • ["Share", "Send", "Post"]
  • ["Share"]
  • []

Mental model. Different visitors enter a building by a ramp, a lift, an intercom or a key card. They all arrive at the same rooms, but only if every entrance is signposted with the same names.

VoiceOver is one of several ways to drive an app, and they all rely on the same accessibility tree. Voice Control lets a person say “tap Share” or “show numbers”; it matches speech against the visible names of elements, which is why an icon-only button with the label “Share” is easier to speak to than one named “Send report”, and why the spoken name should match what is on screen. When the best accessible label is long or differs from the visible text, give alternative names with accessibilityUserInputLabels (.accessibilityInputLabels in SwiftUI), as in the check below, where “Share”, “Send” and “Post” all work. Switch Control scans through elements one at a time and selects with a switch, so the number of elements, their order and grouping directly decide how many steps a task costs: group related items, avoid tiny tap targets, and make sure every action is reachable without a gesture.

Full Keyboard Access and a hardware keyboard let a person move between controls with Tab and the arrow keys and activate them with Space or Return, so controls must be focusable and the focus order logical (UIKit’s focus system and SwiftUI’s focusable and @FocusState); keyboard shortcuts help here. Braille displays, Speak Screen and AssistiveTouch use the same labels and structure. On tvOS the focus engine is the accessibility model: VoiceOver reads whatever has focus, so every focusable item needs a good label and the focus path must reach everything (Q420). The common thread is that nothing should depend on a gesture, a colour or a precise tap alone, and that order and naming matter as much as presence. Test with Voice Control (“show numbers”, “show names”) and Switch Control on a device, not only VoiceOver.

The alternative names are stored on the element and used by Voice Control to match speech.

Common traps

  • A label that differs from the visible text. A Voice Control user says what they see, and it does not match; add input labels.
  • Dozens of ungrouped tiny elements. Switch Control users then need many steps for one task.

They might follow up with

  • How does Voice Control find a button? By matching the spoken name to the element’s label or input labels, or by number overlays.
  • What makes keyboard use work? Focusable controls in a logical order, visible focus, and activation with standard keys.

Related questions

  • 24.1.1 How does VoiceOver read your UI: accessibility elements, labels, values, hints and traits, and how do you fix…
  • 24.1.2 How do custom actions, adjustable controls, rotors and announcements make complex UI usable with VoiceOver?
  • 24.5.1 How do you test accessibility: the Accessibility Inspector, automated audits in XCUITest, identifiers versus…
  • 20.4.1 How does the tvOS focus engine work: focusable items, preferred focus, focus guides, and SwiftUI’s focusable…

← How do custom actions, adjustable controls, rotors and announcements…