Accessibility Trait: essentie, welke typen er zijn en hoe ze werken in ontwikkeling

Auteur: IT Sectr Gepubliceerd: 2026-05-16 Leestijd: 9 min

Accessibility Trait — is een eigenschap van een iOS-element die de rol en het gedrag voor VoiceOver bepaalt. De trait vertelt de schermlezer hoe het element moet worden uitgesproken en welke gebaren beschikbaar zijn: of het een knop, koptekst, link of zoekveld is. Volgens Apple UIAccessibilityTraits, 2024 ondersteunt het systeem 15+ constanten die kunnen worden gecombineerd met een bitmasker. Een correct gekozen trait bespaart tot 50% navigatietijd voor VoiceOver-gebruikers.

Belangrijkste punten

  • Accessibility Trait — de rol van een iOS-element voor VoiceOver; wordt ingesteld via de constanten UIAccessibilityTraits
  • Traits kunnen worden gecombineerd met de operator | om complexe rollen te maken (knop + geselecteerd)
  • Elk element kan tegelijkertijd meerdere traits hebben, maar niet meer dan 3-4 om verwarring te voorkomen
  • Een verkeerde trait (bijv. StaticText voor een knop) verbreekt het interactiescenario: de gebruiker weet niet of het gebaar beschikbaar is
  • In Android is het equivalent de attributen role en className in AccessibilityNodeInfo

Wat is Accessibility Trait

Accessibility Trait — een vlag die op een UIView-element wordt gezet om de semantische rol voor VoiceOver aan te geven. De trait is een van de drie componenten van Apple’s accessibility-triade: Label (naam), Hint (beschrijving), Trait (rol). iOS gebruikt het bitmasker UIAccessibilityTraits (UInt64), waarbij elke bit overeenkomt met een specifieke rol. VoiceOver leest de rol na Label en Hint: „Knop Verzenden. Opent formulier“ — „Knop“ is toegevoegd dankzij de trait UIAccessibilityTraitButton.

Standaard krijgt UIButton UIAccessibilityTraitButton, UILabel — UIAccessibilityTraitStaticText, UIImageView — UIAccessibilityTraitImage. Bij het gebruik van aangepaste besturingselementen moet de ontwikkelaar de trait handmatig instellen. Apple Human Interface Guidelines, 2024, noemen dit „een van de meest kritieke stappen bij het waarborgen van accessibility“.

Zonder de juiste trait weet de gebruiker niet welk gebaar toe te passen: enkel tikken (activeren van knop), dubbeltikken (vergroten) of veeggebaar (schakelaar). De trait bepaalt welke gebaren VoiceOver op het element activeert.

Technische implementatie van UIAccessibilityTraits

UIAccessibilityTraits — is een typealias UInt64. Elke trait is een constante waarin precies één bit is ingesteld. Bijvoorbeeld UIAccessibilityTraitButton = 0x0000000000000001, UIAccessibilityTraitLink = 0x0000000000000002, UIAccessibilityTraitHeader = 0x0000000000000008. Combinatie wordt bereikt via bitsgewijze OF: 0x0001 | 0x0008 = 0x0009. VoiceOver analyseert het masker en bepaalt het gedrag.

Belangrijkste typen iOS-traits

iOS biedt meer dan 15 trait-constanten. Laten we de belangrijkste bekijken, die in 90% van de scenario’s worden gebruikt:

TraitConstanteVoiceOver-gedrag
ButtonUIAccessibilityTraitButtonActiveren door dubbeltikken
HeaderUIAccessibilityTraitHeaderSnelle navigatie door kopteksten
LinkUIAccessibilityTraitLinkActiveren als link
StaticTextUIAccessibilityTraitStaticTextAlleen lezen, zonder activering
SearchFieldUIAccessibilityTraitSearchFieldZoekveld met speciaal gedrag
ImageUIAccessibilityTraitImageAfbeelding, zonder activeringsgebaar
SelectedUIAccessibilityTraitSelectedStatus „geselecteerd“
PlaysSoundUIAccessibilityTraitPlaysSoundSpeelt geluid bij activering
KeyboardKeyUIAccessibilityTraitKeyboardKeyToets op toetsenbord
TabBarUIAccessibilityTraitTabBarTab-balkelement

De constanten zijn beschikbaar in UIKit sinds iOS 3.0. In iOS 14+ is ondersteuning voor UIAccessibilityTraits in SwiftUI toegevoegd via de modifier .accessibilityAddTraits().

Zeldzame maar nuttige traits

UIAccessibilityTraitAdjustable — voor instelbare waarden (schuifregelaars, kieswijzers, volumeschuifregelaars). VoiceOver maakt vegen omhoog/omlaag mogelijk om de waarde te wijzigen met een stap die is gedefinieerd via accessibilityIncrement en accessibilityDecrement. UIAccessibilityTraitUpdatesFrequently — voor elementen met een vaak veranderende waarde (timer, laadindicator). VoiceOver leest de waarde niet bij elke wijziging, maar neemt een pauze. UIAccessibilityTraitAllowsDirectInteraction — voor elementen waarmee de gebruiker direct kan interacteren (toetsenbord, tekengereedschap), zonder VoiceOver-gebaren.

Traits combineren

Een element kan tegelijkertijd meerdere traits hebben — de combinatie wordt gespecificeerd met bitsgewijze OF (|). Voorbeeld: een knop die momenteel is geselecteerd — Button | Selected. VoiceOver zegt: „Geselecteerd. Gefilterd op prijs. Knop“.

Traits instellen in code:

swift
filterButton.accessibilityTraits.insert(.button)
filterButton.accessibilityTraits.insert(.selected)

// Of via masker:
filterButton.accessibilityTraits = [.button, .selected]

Voor aangepaste UIView waar de trait niet standaard is ingesteld:

swift
class CustomToggle: UIControl {
    override var accessibilityTraits: UIAccessibilityTraits {
        get {
            if isOn {
                return [.button, .selected]
            } else {
                return .button
            }
        }
        set {}
    }
}

Combinatieregel: niet meer dan 3-4 traits per element. Overmatige traits (bijv. Button + Link + Header) maken de VoiceOver-aankondiging te lang en verwarrend. Volgens Apple „verhoogt elke extra eigenschap de cognitieve belasting van de gebruiker“.

SwiftUI: trait-modifiers

In SwiftUI worden traits ingesteld via de modifiers .accessibilityAddTraits() en .accessibilityRemoveTraits(). Voorbeeld: Text(„Koptekst“).font(.largeTitle).accessibilityAddTraits(.isHeader). De modifier .isHeader voegt UIAccessibilityTraitHeader toe. Lijst van SwiftUI-traits: .isButton, .isHeader, .isLink, .isSelected, .isImage, .isSearchField, .isKeyboardKey, .isStaticText, .isSummaryElement, .isToggle, .playsSound, .startsMediaSession, .updatesFrequently, .allowsDirectInteraction, .causesPageTurn, .isModal, .tabBar.

Veelgemaakte fouten bij het kiezen van een trait

StaticText in plaats van Button — een aangepast besturingselement dat er visueel uitziet als een knop krijgt standaard de trait StaticText. VoiceOver biedt geen activeringsgebaar, de gebruiker kan het element niet „ indrukken“. Oplossing: stel expliciet .button in.

Image zonder trait — UIImageView met ingeschakelde accessibility krijgt de trait Image, zelfs als het eigenlijk een knop is om een foto te vergroten. Wijs .button en Label „Vergroot foto“ toe. Volgens WWDC 2023, „Deliver an Exceptional Accessibility Experience“ wordt 40% van de accessibility-regressies in nieuwe versies van apps precies veroorzaakt door niet-overeenkomende traits.

Header op elk element — de trait Header is bedoeld voor structurele kopteksten van het scherm. Als je elke UILabel een koptekst maakt, wordt de VoiceOver-rotor in de modus „Kopteksten“ nutteloos — hij stopt bij elk woord.

Hoe te corrigeren: checklist

  • Elk interactief aangepast element krijgt de trait Button, Link of Adjustable
  • Sectiekopteksten krijgen de trait Header (niet StaticText)
  • Afbeeldingsknoppen krijgen de trait Button + Selected in de geselecteerde status
  • Elementen zonder gebaar — StaticText of Image (alleen lezen)

Regressiefouten bij het wijzigen van UIButton naar UIControl

Veelvoorkomende oorzaak van trait-verlies — refactoring: de ontwikkelaar vervangt UIButton door UIControl voor aangepaste weergave. UIButton krijgt automatisch de trait Button, UIControl — niet. Na refactoring moet expliciet accessibilityTraits = .button worden ingesteld. Voeg een controle toe in code review: „Als je UIButton hebt vervangen door UIControl — controleer de trait“.

Traits en dynamische toestanden

Voor elementen met een veranderende toestand (bijv. like-knop) moet de trait dynamisch veranderen. In de status „niet geliket“ — Button, in de status „geliket“ — Button + Selected + Image (als er een pictogram is). VoiceOver verandert de aankondiging: „Vind ik leuk. Knop“ vs „Geselecteerd. Vind ik leuk. Knop“. Gebruik accessibilityValue om de status door te geven als de trait Selected niet voldoende is. Relevant voor abonneer-, favorieten-, filter- en schakelknoppen.

Android-equivalent: role en className

In Android is er geen direct equivalent van traits. In plaats van een bitmasker worden gebruikt:

  • className — de waarde van AccessibilityNodeInfo.className (android.widget.Button, android.widget.TextView)
  • role — attribuut in XML (rol wordt bepaald door het View-type)
  • stateDescription — equivalent van Selected: toevoegen van statusbeschrijving (ingeschakeld/uitgeschakeld)

Voor aangepaste Views in Android moet onInitializeAccessibilityNodeInfo worden overschreven:

kotlin
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-ontwikkelaars moeten de parameter semanticsRole in de Semantics-widget gebruiken: button, header, image, link, textField en andere. Daarnaast zijn semanticsLabel en semanticsHint beschikbaar — het volledige equivalent van de iOS-triade Label + Hint + Trait.

Web-equivalenten: WAI-ARIA role

Voor webversies van mobiele apps (PWA, WebView) wordt het attribuut role uit WAI-ARIA gebruikt: role="button", role="heading", role="link". Dit is het directe equivalent van accessibilityTraits. In hybride apps controleer of WebView ARIA-rollen doorgeeft aan de native accessibility-laag. Gebruik hiervoor het protocol UIAccessibilityContainerDataTable in iOS of setAccessibilityDelegate in Android. WebView met ingeschakelde JavaScript geeft mogelijk ARIA-rollen niet correct door — test apart.

AccessibilityNodeInfo: extra acties

In Android kunnen aangepaste acties worden toegevoegd aan AccessibilityNodeInfo: AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK en ACTION_LONG_CLICK. Dit is het equivalent van de trait Button met extra gebaren. Gebruik voor schuifregelaars ACTION_SET_PROGRESS — equivalent van Adjustable. Voor Spinner en DatePicker — ACTION_SET_SELECTION, ACTION_SET_DATE en ACTION_SET_TIME.

Traits controleren en testen

Xcode Accessibility Inspector — het belangrijkste hulpmiddel voor iOS: selecteer het element en bekijk het veld Traits. Het toont de lijst met ingestelde traits. De VoiceOver-rotor in de modus „Elementen“ maakt het mogelijk door alle besturingselementen van het scherm te gaan.

Geautomatiseerde test in Swift voor het controleren van een trait:

swift
func testSubmitButtonTrait() {
    let app = XCUIApplication()
    app.launch()
    let submitButton = app.buttons["Verzenden"]
    XCTAssertTrue(submitButton.isEnabled)
    // XCUIElement biedt geen directe toegang tot traits
    // Controle via activering van gebaar
    submitButton.tap()
    XCTAssertTrue(app.staticTexts["Formulier verzonden"].exists)
}

Handmatige controle via VoiceOver: schakel VoiceOver in, beweeg je vinger naar het element, tik tweemaal — het element moet worden geactiveerd als het een Button is. Als het element niet reageert op dubbeltikken, is de trait onjuist. Gebruik het Rotor-gebaar om te schakelen tussen modi („Kopteksten“, „Links“, „Knoppen“) — elke modus toont alleen elementen met de bijbehorende trait.

Unit-testen van traits in iOS

Vóór iOS 14 hadden unit-tests geen directe toegang tot accessibilityTraits. Vanaf iOS 14 is de eigenschap beschikbaar: XCTAssertEqual(customButton.accessibilityTraits, .button). Gebruik dit in modulaire tests voor het controleren van aangepaste besturingselementen. Het wordt aanbevolen om elke nieuwe aangepaste UIView te testen op correctheid van de trait, vooral na refactoring of wijziging van de bovenliggende klasse.

Veelgestelde vragen

Hoeveel traits kunnen voor een element worden ingesteld?

Tot 3-4 traits per element. Een groter aantal maakt de VoiceOver-aankondiging overbodig. Gebruik combinaties: Button + Selected, Header + StaticText.

Wat is de standaard trait van UIButton?

UIAccessibilityTraitButton. iOS stelt deze automatisch in voor alle instanties van UIButton. Als je overerft van UIView en een knop nabootst, moet de trait handmatig worden ingesteld.

Bestaat de trait „Adjustable“ en waarvoor dient deze?

Ja, UIAccessibilityTraitAdjustable — voor elementen met een instelbare waarde (schuifregelaars, kieswijzers, tellers). VoiceOver maakt vegen omhoog/omlaag mogelijk om de waarde te wijzigen en leest de huidige status.

Hoe controleer ik traits in SwiftUI?

Gebruik de modifier .accessibilityAddTraits(): Text(„Koptekst“).font(.title).accessibilityAddTraits(.isHeader). De methode werkt op iOS 14+.

Wat gebeurt er als ik geen trait instel voor een aangepast besturingselement?

VoiceOver kent de trait None toe. Het element krijgt geen rol — de schermlezer leest alleen Label zonder het type te specificeren. De gebruiker weet niet of het activeringsgebaar beschikbaar is.

Samenvatting

  • Accessibility Trait — het bitmasker UIAccessibilityTraits dat de rol van een iOS-element voor VoiceOver bepaalt (Button, Header, Link, StaticText en andere)
  • Traits worden gecombineerd via bitsgewijze OF ([] in Swift), maximaal 3-4 per element
  • Aangepaste UIView moeten een expliciete trait krijgen — standaard kan dit None of Image zijn
  • In Android wordt de rol ingesteld via className in AccessibilityNodeInfo, in Flutter via semanticsRole
  • Een verkeerde trait (StaticText voor een knop) verbreekt het VoiceOver-scenario: geen activeringsgebaar
  • Controleer traits via Accessibility Inspector in Xcode en de VoiceOver-rotor
  • In SwiftUI gebruik je .accessibilityAddTraits() voor het declaratief instellen van traits

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook