Accessibility Trait ist eine Eigenschaft eines iOS-Elements, die seine Rolle und sein Verhalten für VoiceOver bestimmt. Der Trait teilt dem Screenreader mit, wie das Element angesagt werden soll und welche Gesten verfügbar sind: ob es sich um eine Schaltfläche, eine Überschrift, einen Link oder ein Suchfeld handelt. Laut Apple UIAccessibilityTraits, 2024 unterstützt das System über 15 Konstanten, die mit einer Bitmaske kombiniert werden können. Ein richtig gewählter Trait spart VoiceOver-Benutzern bis zu 50% der Navigationszeit.
Wichtige Punkte
Accessibility Trait ist ein Flag, das auf einem UIView-Element gesetzt wird, um VoiceOver seine semantische Rolle mitzuteilen. Der Trait ist eine der drei Komponenten von Apples Accessibility-Triade: Label (Name), Hint (Beschreibung), Trait (Rolle). iOS verwendet die Bitmaske UIAccessibilityTraits (UInt64), bei der jedes Bit einer bestimmten Rolle entspricht. VoiceOver liest die Rolle nach Label und Hint: „Senden-Schaltfläche. Öffnet ein Formular“ – „Schaltfläche“ wird dank des Traits UIAccessibilityTraitButton hinzugefügt.
Standardmäßig erhält UIButton UIAccessibilityTraitButton, UILabel erhält UIAccessibilityTraitStaticText, UIImageView erhält UIAccessibilityTraitImage. Bei benutzerdefinierten Steuerelementen muss der Entwickler den Trait manuell setzen. Apple Human Interface Guidelines, 2024, bezeichnen dies als „einen der kritischsten Schritte zur Gewährleistung der Barrierefreiheit“.
Ohne den richtigen Trait weiß der Benutzer nicht, welche Geste anzuwenden ist: Einzelfinger-Tipp (Schaltflächenaktivierung), Doppeltipp (Vergrößerung) oder Wischgeste (Umschalter). Der Trait bestimmt, welche VoiceOver-Gesten auf dem Element aktiviert werden.
UIAccessibilityTraits ist ein typealias UInt64. Jeder Trait ist eine Konstante, bei der genau ein Bit gesetzt ist. Zum Beispiel UIAccessibilityTraitButton = 0x0000000000000001, UIAccessibilityTraitLink = 0x0000000000000002, UIAccessibilityTraitHeader = 0x0000000000000008. Kombinationen werden durch bitweises ODER erreicht: 0x0001 | 0x0008 = 0x0009. VoiceOver analysiert die Maske und bestimmt das Verhalten.
iOS bietet über 15 Trait-Konstanten. Betrachten wir die wichtigsten, die in 90% der Szenarien verwendet werden:
| Trait | Konstante | VoiceOver-Verhalten |
|---|---|---|
| Button | UIAccessibilityTraitButton | Aktivierung durch Doppeltipp |
| Header | UIAccessibilityTraitHeader | Schnellnavigation durch Überschriften |
| Link | UIAccessibilityTraitLink | Aktivierung als Link |
| StaticText | UIAccessibilityTraitStaticText | Nur Lesen, keine Aktivierung |
| SearchField | UIAccessibilityTraitSearchField | Suchfeld mit speziellem Verhalten |
| Image | UIAccessibilityTraitImage | Bild, kein Aktivierungsgestus |
| Selected | UIAccessibilityTraitSelected | Zustand „ausgewählt“ |
| PlaysSound | UIAccessibilityTraitPlaysSound | Spielt bei Aktivierung einen Ton ab |
| KeyboardKey | UIAccessibilityTraitKeyboardKey | Tastaturtaste |
| TabBar | UIAccessibilityTraitTabBar | Registerkartenleistenelement |
Die Konstanten sind seit iOS 3.0 in UIKit verfügbar. iOS 14+ hat die UIAccessibilityTraits-Unterstützung in SwiftUI über den Modifikator .accessibilityAddTraits() hinzugefügt.
UIAccessibilityTraitAdjustable – für einstellbare Werte (Schieberegler, Picker, Lautstärkeregler). VoiceOver ermöglicht das Wischen nach oben/unten, um den Wert mit einer Schrittweite zu ändern, die über accessibilityIncrement und accessibilityDecrement definiert wird. UIAccessibilityTraitUpdatesFrequently – für Elemente mit sich häufig ändernden Werten (Timer, Fortschrittsanzeige). VoiceOver liest den Wert nicht bei jeder Änderung vor, sondern macht eine Pause. UIAccessibilityTraitAllowsDirectInteraction – für Elemente, mit denen der Benutzer direkt interagieren kann (Tastatur, Zeichen-App), ohne VoiceOver-Gesten.
Ein einzelnes Element kann mehrere Traits gleichzeitig haben – die Kombination wird mit bitweisem ODER (|) festgelegt. Beispiel: eine Schaltfläche, die aktuell ausgewählt ist – Button | Selected. VoiceOver sagt an: „Ausgewählt. Nach Preis gefiltert. Schaltfläche.“
Traits im Code setzen:
filterButton.accessibilityTraits.insert(.button)
filterButton.accessibilityTraits.insert(.selected)
// Oder per Maske:
filterButton.accessibilityTraits = [.button, .selected]
Für benutzerdefinierte UIView, bei denen der Trait standardmäßig nicht gesetzt ist:
class CustomToggle: UIControl {
override var accessibilityTraits: UIAccessibilityTraits {
get {
if isOn {
return [.button, .selected]
} else {
return .button
}
}
set {}
}
}
Kombinationsregel: nicht mehr als 3–4 Traits pro Element. Übermäßige Traits (z. B. Button + Link + Header) machen die VoiceOver-Ansage zu lang und verwirrend. Laut Apple „erhöht jede zusätzliche Eigenschaft die kognitive Belastung des Benutzers“.
In SwiftUI werden Traits mit den Modifikatoren .accessibilityAddTraits() und .accessibilityRemoveTraits() gesetzt. Beispiel: Text(„Titel“).font(.largeTitle).accessibilityAddTraits(.isHeader). Der Modifikator .isHeader fügt UIAccessibilityTraitHeader hinzu. SwiftUI-Trait-Liste: .isButton, .isHeader, .isLink, .isSelected, .isImage, .isSearchField, .isKeyboardKey, .isStaticText, .isSummaryElement, .isToggle, .playsSound, .startsMediaSession, .updatesFrequently, .allowsDirectInteraction, .causesPageTurn, .isModal, .tabBar.
StaticText statt Button – ein benutzerdefiniertes Steuerelement, das visuell wie eine Schaltfläche aussieht, erhält standardmäßig den Trait StaticText. VoiceOver bietet keinen Aktivierungsgestus an, sodass der Benutzer das Element nicht „drücken“ kann. Lösung: explizit .button setzen.
Bild ohne Trait – UIImageView mit aktivierter Barrierefreiheit erhält den Trait Image, auch wenn es sich tatsächlich um eine Schaltfläche zum Vergrößern eines Fotos handelt. Weisen Sie .button und Label „Foto vergrößern“ zu. Laut WWDC 2023, „Deliver an Exceptional Accessibility Experience“ werden 40% der Barrierefreiheits-Rergressionen in neuen App-Versionen durch Trait-Ungleichheit verursacht.
Header auf jedem Element – der Header-Trait ist für strukturelle Bildschirmüberschriften gedacht. Wenn jede UILabel zu einer Überschrift gemacht wird, wird der VoiceOver-Rotor im Modus „Überschriften“ nutzlos – er stoppt bei jedem Wort.
Eine häufige Ursache für Trait-Verlust ist Refactoring: Ein Entwickler ersetzt UIButton durch UIControl für eine benutzerdefinierte Darstellung. UIButton erhält automatisch den Trait Button, UIControl nicht. Nach dem Refactoring müssen Sie explizit accessibilityTraits = .button setzen. Fügen Sie eine Prüfung im Code-Review hinzu: „Wenn Sie UIButton durch UIControl ersetzt haben – überprüfen Sie den Trait.“
Bei Elementen mit wechselndem Zustand (z. B. einem Like-Button) sollte sich der Trait dynamisch ändern. Im Zustand „nicht geliked“ – Button, im Zustand „geliked“ – Button + Selected + Image (falls ein Symbol vorhanden ist). VoiceOver ändert die Ansage: „Gefällt mir. Schaltfläche.“ vs. „Ausgewählt. Gefällt mir. Schaltfläche.“ Verwenden Sie accessibilityValue, um den Zustand zu übermitteln, wenn der Selected-Trait nicht ausreicht. Relevant für Abonnement-Buttons, Favoriten, Filter und Umschalter.
In Android gibt es keine direkte Entsprechung zu Traits. Statt einer Bitmaske werden verwendet:
Für benutzerdefinierte Views in Android müssen Sie onInitializeAccessibilityNodeInfo überschreiben:
class CustomButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : View(context, attrs) {
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.className = "android.widget.Button"
info.isClickable = true
}
}
Flutter-Entwickler sollten den Parameter semanticsRole im Semantics-Widget verwenden: button, header, image, link, textField und andere. Zusätzlich stehen semanticsLabel und semanticsHint zur Verfügung – eine vollständige Entsprechung der iOS-Triade Label + Hint + Trait.
Für Web-Versionen mobiler Apps (PWA, WebView) wird das Attribut role aus WAI-ARIA verwendet: role="button", role="heading", role="link". Dies ist eine direkte Entsprechung von accessibilityTraits. In Hybrid-Apps überprüfen Sie, ob WebView ARIA-Rollen an die native Accessibility-Schicht weitergibt. Verwenden Sie dazu das Protokoll UIAccessibilityContainerDataTable unter iOS oder setAccessibilityDelegate unter Android. WebView mit aktiviertem JavaScript kann ARIA-Rollen möglicherweise nicht korrekt weitergeben – testen Sie separat.
In Android können Sie benutzerdefinierte Aktionen zu AccessibilityNodeInfo hinzufügen: AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK und ACTION_LONG_CLICK. Dies entspricht dem Button-Trait mit zusätzlichen Gesten. Für Schieberegler verwenden Sie ACTION_SET_PROGRESS – Entsprechung von Adjustable. Für Spinner und DatePicker – ACTION_SET_SELECTION, ACTION_SET_DATE und ACTION_SET_TIME.
Xcode Accessibility Inspector ist das primäre Tool für iOS: Wählen Sie ein Element aus und sehen Sie sich das Feld Traits an. Es zeigt die Liste der gesetzten Traits. Der VoiceOver-Rotor im Modus „Elemente“ ermöglicht die Navigation durch alle Steuerelemente des Bildschirms.
Automatisierter Swift-Test zur Überprüfung eines Traits:
func testSubmitButtonTrait() {
let app = XCUIApplication()
app.launch()
let submitButton = app.buttons["Senden"]
XCTAssertTrue(submitButton.isEnabled)
// XCUIElement bietet keinen direkten Zugriff auf Traits
// Überprüfung durch Gestenaktivierung
submitButton.tap()
XCTAssertTrue(app.staticTexts["Formular gesendet"].exists)
}
Manuelle Überprüfung via VoiceOver: Schalten Sie VoiceOver ein, wischen Sie zum Element, tippen Sie zweimal – das Element sollte aktiviert werden, wenn es sich um eine Schaltfläche handelt. Wenn das Element nicht auf Doppeltipp reagiert, ist der Trait falsch. Verwenden Sie die Rotor-Geste, um zwischen den Modi zu wechseln („Überschriften“, „Links“, „Schaltflächen“) – jeder Modus zeigt nur Elemente mit dem entsprechenden Trait.
Vor iOS 14 hatten Unit-Tests keinen direkten Zugriff auf accessibilityTraits. Ab iOS 14 ist die Eigenschaft verfügbar: XCTAssertEqual(customButton.accessibilityTraits, .button). Verwenden Sie dies in Unit-Tests, um benutzerdefinierte Steuerelemente zu überprüfen. Es wird empfohlen, jedes neue benutzerdefinierte UIView auf korrekte Traits zu testen, insbesondere nach Refactoring oder Änderung der Elternklasse.
Häufig gestellte Fragen
Bis zu 3–4 Traits pro Element. Eine größere Anzahl macht die VoiceOver-Ansage redundant. Verwenden Sie Kombinationen: Button + Selected, Header + StaticText.
UIAccessibilityTraitButton. iOS setzt ihn automatisch für alle UIButton-Instanzen. Wenn Sie von UIView erben und eine Schaltfläche simulieren, muss der Trait manuell gesetzt werden.
Ja, UIAccessibilityTraitAdjustable – für Elemente mit einstellbaren Werten (Schieberegler, Picker, Zähler). VoiceOver ermöglicht das Wischen nach oben/unten, um den Wert zu ändern und den aktuellen Zustand vorzulesen.
Verwenden Sie den Modifikator .accessibilityAddTraits(): Text(„Titel“).font(.title).accessibilityAddTraits(.isHeader). Die Methode funktioniert ab iOS 14+.
VoiceOver weist den Trait None zu. Das Element erhält keine Rolle – der Screenreader liest nur das Label ohne Angabe des Typs. Der Benutzer erfährt nicht, ob ein Aktivierungsgestus verfügbar ist.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch