← Alle Beitrage

Barrierefreiheit in iOS 27: Lese-Apps und benutzerdefinierte Steuerelemente

Das Lesen von Langtexten ist ein anderes Problem als das Navigieren durch eine Benutzeroberfläche: Es geht darum, sich flüssig durch den Text zu bewegen, und nicht von Steuerelement zu Steuerelement zu springen. Genau entlang dieser Naht teilen sich die beiden Barrierefreiheits-Sessions der WWDC26 auf: eine für die Leseoberfläche, eine für die Steuerelemente, die sie umgeben.

Diese Aufteilung ist deshalb wichtig, weil die Lösungen grundsätzlich verschieden sind. Die Schwächen einer Lese-App betreffen die Kontinuität: Text, der sich über Absätze hinweg nicht verbinden lässt, ein Vorlesen, das am unteren Seitenrand stehen bleibt. Die Schwächen eines benutzerdefinierten Steuerelements betreffen die Übersetzung: eine Geste, die visuell alles vermittelt und VoiceOver nichts. iOS 27 liefert APIs für beide Fälle, und eine davon, accessibilityLinkedGroup, ist in diesem Jahr neu.

TL;DR

  • Lese-Apps sollten zuerst zu den System-Textansichten greifen. UITextView, TextEditor und Text mit aktivierter Auswahl übernehmen das UITextInput-Protokoll und erhalten Navigation nach Zeile, Wort und Zeichen sowie Auswahl kostenlos1.
  • Wenn das Layout getrennte Textelemente erzwingt, verknüpfen Sie sie, damit VoiceOver über die Naht hinweg navigieren kann. iOS 18 führte accessibilityNextTextNavigationElement/accessibilityPreviousTextNavigationElement ein; iOS 27 ergänzt für denselben Effekt den SwiftUI-Modifier accessibilityLinkedGroup1.
  • Bei paginierten Inhalten sorgt das Merkmal causesPageTurn in Kombination mit accessibilityScroll dafür, dass „Bildschirm sprechen” und VoiceOver die Seiten beim Vorlesen automatisch weiterblättern1.
  • Eigens gerenderter Text (eingescannte Seiten, anspruchsvolle Typografie) verliert all das. Wer UITextInput vollständig übernimmt, stellt es wieder her: die Geometrie über selectionRects, Teilzeichenfolgen über textInRange und ein Tokenizer für die Navigation nach Zeile, Wort und Zeichen1.
  • Benutzerdefinierte Steuerelemente folgen vier Leitprinzipien: Zweck, Wert, Aktionen, Rückmeldung. Die Werkzeuge dafür sind accessibilityLabel/accessibilityValue, das .adjustable-Merkmal mit accessibilityAdjustableAction, benutzerdefinierte Aktionen für mehrachsige Steuerelemente und Direct Touch (allowsDirectInteraction) für gestenlastige Oberflächen2.

Lese-Apps: Text verbinden, den das Layout auseinandergerissen hat

Die Session zu Lese-Apps ist um eine trügerisch einfache Einschränkung herum aufgebaut. Die Reiseführer-App des Vortragenden verwendet für jeden Absatz eine eigene UITextView, weil das Layout es so verlangte, statt einer einzigen Ansicht, die die ganze Seite enthält1. Jede einzelne Textansicht ist für sich genommen barrierefrei. Das Problem zeigt sich an der Grenze zwischen ihnen.

Watch on Apple Developer ↗
Apple zeigt, wie VoiceOver innerhalb eines Absatzes Zeile für Zeile festhängt und nicht in den nächsten Absatz übergehen kann, weil jeder Absatz eine eigene Ansicht ist – und verbindet sie anschließend mit den APIs für Textnavigationselemente.

Der Vortragende setzt drei Ziele für die App: granulare Textnavigation, damit VoiceOver und „Bildschirm sprechen” sich flüssig durch den Text bewegen, ein durchgehendes Leseerlebnis ohne Unterbrechungen sowie vollständige Textauswahl1. Der Rest der Session ist ein Rundgang durch die Frage, welche API welches Ziel erfüllt.

Für die Navigation über getrennte Ansichten hinweg lautet die Antwort: die APIs für Textnavigationselemente, die mit iOS 18 eingeführt wurden. Für jedes Textelement geben Sie das nächste und das vorige barrierefreie Textelement zurück, zu dem VoiceOver wechseln soll. Im Beispiel der Session liefert Absatz 1 über sein accessibilityNextTextNavigationElement den Absatz 2 zurück, und Absatz 2 liefert über sein accessibilityPreviousTextNavigationElement den Absatz 11. Ist das einmal verdrahtet, bewegt sich VoiceOver über das Ende eines Absatzes hinaus zur ersten Zeile des nächsten, statt den Sackgassen-Ton abzuspielen.

Die Neuerung in iOS 27 ist in SwiftUI angesiedelt. Wie der Vortragende es formuliert: Ab iOS 27 erzielt das Verknüpfen mehrerer Textelemente über den Modifier accessibilityLinkedGroup denselben Effekt1. Sie geben den verknüpften Elementen dieselbe id und denselben namespace, und sie erben das elementübergreifende Textnavigationsverhalten – ohne die manuelle Buchführung über das nächste und vorige Element. AppKit erhält für dasselbe Ergebnis auf dem Mac das entsprechende accessibilitySharedTextUIElements1. Der Beitrag Woraus SwiftUI gemacht ist aus demselben Cluster behandelt, wie sich SwiftUI-Modifier wie dieser bis hinunter auf den zugrunde liegenden Barrierefreiheitsbaum auflösen.

Kontinuität ist das zweite Ziel. Paginierte Inhalte erfordern Wischgesten, und ein Vorlesen sollte die Seitengrenzen so ignorieren, wie es ein Hörbuch tut. In der Session bleibt „Bildschirm sprechen” am unteren Rand der ersten Seite abrupt stehen, bis der Vortragende dem letzten Absatz jeder Seite das Merkmal causesPageTurn zuweist. In Kombination mit accessibilityScroll scrollen „Bildschirm sprechen” und VoiceOver dann automatisch zur nächsten Seite, sobald sie das Ende erreichen, und das Merkmal steht sowohl in UIKit als auch in SwiftUI zur Verfügung1.

Das dritte Ziel, die Auswahl, ergibt sich bei System-Textansichten größtenteils von selbst, doch die Session fügt einen durchdachten Akzent hinzu: eine Aktion „Empfehlung speichern”, die über den Bearbeitungsrotor von VoiceOver bereitgestellt wird. Der Vortragende überschreibt accessibilityCustomActions in der Absatz-Textansicht und erstellt die benutzerdefinierte Aktion mit der Kategorie „edit”, gerade damit sie im Bearbeitungsrotor neben den Textauswahl-Vorgängen erscheint und nicht als generische Aktion1. Die Empfehlung ist eindeutig: Verwenden Sie die Kategorie „edit”, wenn eine benutzerdefinierte Aktion mit der Textauswahl verknüpft ist.

Wenn Sie Ihren Text selbst rendern: UITextInput in voller Tiefe

Die zweite Hälfte der Lese-Session behandelt den Fall, in dem Systemansichten keine Option sind. Eigener Text tritt in spezialisierten Lese-Apps für anspruchsvolle Typografie, in App-übergreifend geteiltem Code oder bei eingescannten Seiten auf, und das Beispiel des Vortragenden ist das zugespitzteste: Er ersetzt die Textansichten des Reiseführers durch eingescannte Seiten aus einem handgeschriebenen Notizbuch. Der Preis dafür ist total. Der Wechsel zu Bildern verliert das Barrierefreiheitsverhalten, das UITextView kostenlos lieferte, bis hinunter zum Allergrundlegendsten: dem Vorlesen des Textes. VoiceOver sagt nur noch „Bild”1.

Die Lösung besteht darin, das UITextInput-Protokoll zu übernehmen, das auf jedem beliebigen Barrierefreiheitselement sitzen kann und gerenderten Text oder Text in Bildern ebenso barrierefrei macht wie eine Standard-Textansicht1. Der Haken, in der Session unverblümt benannt, ist: Sie müssen es vollständig implementieren, um den vollen Nutzen zu erhalten. Der Vortragende geht die tragenden Bausteine durch:

  • Geometrie. selectionRects berechnet die Hervorhebungsrechtecke für einen gegebenen Bereich. Ausgehend von einem Handschriftbild nutzt der Vortragende die bekannte Höhe und Breite jeder Zeile, um die Rechtecke über eine eigene Funktion selectionRectFromImage anzunähern, und gibt anschließend das zusammengesetzte Array zurück1.
  • Teilzeichenfolgen. textInRange gibt genau den Textabschnitt zurück, nach dem eine assistive Technologie fragt1.
  • Ein Tokenizer. Die Navigation nach Zeile, Satz, Wort oder Zeichen läuft über einen Tokenizer. Die Session leitet von UIKits UITextInputStringTokenizer ab, um ihn an das eigene Layout anzupassen1.

Eine Verfeinerung ist ausdrücklich optional. Damit sich die Auswahl mit Griffen und Hervorhebungen vollständig anfühlt, fügt der Vortragende der Seitenansicht eine UITextInteraction hinzu und ruft das Input-Delegate auf, wenn sich die Auswahl ändert, damit das System die Darstellung aktualisiert. Die Session weist darauf hin, dass UITextInput selbst diesen Schritt nicht verlangt; er rundet das Erlebnis ab, sodass es einer Standard-Textansicht entspricht1. Und UITextInput lässt sich mit den früheren APIs kombinieren, sodass causesPageTurn und die Navigationselemente auch bei eigenem Text funktionieren.

Es gibt einen Nutzen, den die Session hervorhebt und der leicht unterschätzt wird: Diese Arbeit dient nicht nur VoiceOver und „Bildschirm sprechen”. Seit iOS 26 kann der Bedienungshilfen-Reader die Inhalte einer App in einer Darstellung öffnen, die auf leichteres Lesen abgestimmt ist, und dieselben Praktiken für barrierefreien Text verbessern auch dieses Erlebnis1.

Benutzerdefinierte Steuerelemente: Zweck, Wert, Aktionen, Rückmeldung

Die Session zu benutzerdefinierten Steuerelementen beginnt mit einem standardmäßigen SwiftUI-Slider und einer Argumentation darüber, warum er funktioniert. Sie erfassen eine Spur, einen auf halber Strecke positionierten Griff, eine ziehbare Bedienmöglichkeit und sofortige Rückmeldung – alles auf einen Blick. Niemand hat irgendetwas davon erklärt. Dann stellt die Session die naheliegende Frage: Was, wenn jemand den Bildschirm nicht sehen kann? VoiceOver antwortet, indem es „Helligkeit, 50 %, regelbar” vorliest, dazu einen Hinweis, nach oben oder unten zu wischen – was dieselben vier Dinge vermittelt, die visuell sichtbar sind: den Zweck, den Wert, die verfügbare Aktion und die Rückmeldung, während sich der Wert ändert2.

Watch on Apple Developer ↗
Apple verwandelt ein benutzerdefiniertes Kaffeespender-Steuerelement aus einem nackten „Taste, 6 Unzen” in einen regelbaren Slider, den VoiceOver bedienen kann – durch Hinzufügen von Label, Wert und dem .adjustable-Merkmal mit einer Adjustable-Aktion.

Diese vier Worte (Zweck, Wert, Aktionen, Rückmeldung) sind die Leitprinzipien der Session, und jedes Beispiel führt auf sie zurück2. Das erste ist ein Kaffeespender-Steuerelement: nach oben ziehen für mehr Kaffee, nach unten für weniger, wobei der Füllstand die Unzen darstellt. Vor jeder Bearbeitung liest VoiceOver es als generisches „Taste, 6 Unzen” vor, ohne jeden Hinweis darauf, wie sich der Wert ändern lässt2. Die Lösungen erfolgen schrittweise:

  1. Zweck und Wert. accessibilityLabel benennt es als „Kaffeespender”; accessibilityValue gibt den aktuellen Füllstand bekannt2.
  2. Aktion. Das .adjustable-Merkmal teilt VoiceOver mit, dass das Steuerelement auf Wischgesten nach oben/unten reagiert, und accessibilityAdjustableAction stellt eine Closure mit einem Richtungsparameter .increment oder .decrement bereit, um jeden Fall zu behandeln2.

Das ermöglicht die Anpassung in Schritten von einer Unze. Für feinere Steuerung greift die Session zu VoiceOvers eingebauter Durchreich-Geste: ein Doppeltippen-und-Halten, das am accessibilityActivationPoint des Steuerelements beginnt und Berührungsereignisse direkt an das Steuerelement sendet, während sich der Finger bewegt. Der Vortragende setzt den Aktivierungspunkt so, dass er dem aktuellen Füllstand entspricht2. Die Rückmeldung während des Durchreichens ist eine kleine Lektion in Zurückhaltung: Die Session gibt eine Ankündigung nur dann aus, wenn sich der Wert tatsächlich geändert hat und mindestens 0,3 Sekunden vergangen sind – denn jede einzelne Änderung anzukündigen wäre lärmend2.

Das Equalizer-Pad legt die Messlatte höher. Es ist ein zweidimensionales Steuerelement, und die Session bekennt offen, dass .adjustable hier das falsche Werkzeug ist, weil seine Inkrement-/Dekrement-Aktionen nur eine einzige Achse abdecken. Die Antwort sind benutzerdefinierte Aktionen: der Modifier accessibilityAction, viermal angewandt für „nach oben”, „nach rechts”, „nach unten” und „nach links”, wobei jede eine Achse um einen festen, auf den Bereich begrenzten Schritt verschiebt2. Anders als die Adjustable-Aktion unterstützen benutzerdefinierte Aktionen jeden von Ihnen definierten Vorgang, und sie erreichen auch Nutzer von Schaltersteuerung und Sprachsteuerung2.

Direct Touch: Wenn die Gesten der eigentliche Sinn sind

Das letzte Beispiel der Session ist ein virtuelles Katzen-Steuerelement, bei dem man für verschiedene Reaktionen streichelt, tippt und mit den Fingern zwickt. Das Durchreichen passt hier schlecht, merkt der Vortragende an, weil Menschen eine Aktion vielleicht immer wieder wiederholen oder mehrere Gesten verwenden möchten2. Deshalb greift das Steuerelement zu Direct Touch.

Watch on Apple Developer ↗
Apple fügt einem gestengesteuerten Steuerelement den Modifier .accessibilityDirectTouch mit .requiresActivation hinzu, sodass Berührungen direkt an die Katze durchgereicht werden, statt von VoiceOver abgefangen zu werden.

Das Merkmal allowsDirectInteraction kennzeichnet einen Bereich als Direct-Touch-Bereich: Berührungsereignisse gelangen direkt an das Steuerelement, statt von VoiceOver verarbeitet zu werden, sodass jede vom Steuerelement unterstützte Geste funktioniert2. Zwei Optionen prägen das Verhalten. .requiresActivation hält das Steuerelement bis zu einem Doppeltippen untätig, sodass eine Person über den Bildschirm ziehen kann, ohne es versehentlich auszulösen; Direct Touch bleibt anschließend aktiv, bis der Fokus das Element verlässt. .silentOnTouch hält VoiceOver über dem Bereich stumm und ist für Steuerelemente gedacht, die ihr eigenes Audio erzeugen, das die VoiceOver-Sprachausgabe sonst übertönen würde2. Die virtuelle Katze verwendet .accessibilityDirectTouch mit .requiresActivation2.

Die Session schließt mit einem Vorbehalt, der an die Argumentation zur Plattform-Barrierefreiheit in Barrierefreiheit als Plattform anknüpft: Nicht jeder kann Direct-Touch-Gesten ausführen, also bieten Sie wo immer möglich einen anderen Weg an, etwa benutzerdefinierte Aktionen, damit Nutzer von Schaltersteuerung und Sprachsteuerung dieselben Interaktionen erreichen2.

Leitfaden zur Übernahme

Beide Sessions enden mit derselben Anweisung: Schalten Sie VoiceOver ein und prüfen Sie Ihre eigene App. Ganz konkret:

  • Bei einer Leseoberfläche auf System-Textansichten probieren Sie die Vorlesen-Geste, navigieren Sie mit dem Zeilen-Rotor und wählen Sie Text aus. Bleibt ein Vorlesen an einer Seitengrenze stehen, übernehmen Sie causesPageTurn mit accessibilityScroll. Endet die Zeilennavigation zwischen getrennten Textelementen in einer Sackgasse, verknüpfen Sie sie mit den APIs für Navigationselemente (UIKit) oder mit accessibilityLinkedGroup (SwiftUI, iOS 27)1.
  • Wenn Sie Ihren Text selbst rendern, planen Sie eine vollständige Übernahme von UITextInput ein, keine teilweise; das Protokoll ist alles oder nichts, und der optionale Schritt mit UITextInteraction ist das, was die Auswahl nativ wirken lässt1.
  • Bei jedem benutzerdefinierten Steuerelement gehen Sie die vier Prinzipien der Reihe nach durch. Kann ein VoiceOver-Nutzer erkennen, was es ist (Label), in welchem Zustand es sich befindet (Wert), was er tun kann (Adjustable-Merkmal oder benutzerdefinierte Aktionen) und was geschehen ist (Ankündigungen)? Reservieren Sie Direct Touch für Steuerelemente, deren Wert die Geste selbst ist, und kombinieren Sie es mit einer nicht-gestischen Ausweichlösung2.

Das wiederkehrende Motiv: Greifen Sie zuerst zu Systemkomponenten, und behandeln Sie den eigenen Weg als die Ausnahme, die echte, vollständige Arbeit verlangt. Der Beitrag Die drei Oberflächen einer iOS-App fasst Barrierefreiheit als erstklassige Oberfläche neben der sichtbaren Benutzeroberfläche und den App Intents auf; diese Sessions zeigen, wie es aussieht, diese Oberfläche bei Text und Steuerelementen richtig hinzubekommen.

FAQ

Was ist die neue Barrierefreiheits-API in iOS 27 für Lese-Apps?

Der SwiftUI-Modifier accessibilityLinkedGroup. Ab iOS 27 verleiht das Verknüpfen mehrerer Textelemente mit derselben id und demselben namespace ihnen eine elementübergreifende Textnavigation, sodass VoiceOver von der letzten Zeile eines Elements zur ersten Zeile des nächsten wechselt. Es ist das SwiftUI-Äquivalent der iOS-18-APIs accessibilityNextTextNavigationElement/accessibilityPreviousTextNavigationElement und von AppKits accessibilitySharedTextUIElements1.

Muss ich UITextInput implementieren, wenn ich eine Standard-Textansicht verwende?

Nein. UITextView (UIKit), TextEditor und Text mit aktivierter Auswahl (SwiftUI) sowie NSTextView (AppKit) übernehmen UITextInput bereits und liefern Navigation nach Zeile, Wort und Zeichen sowie Auswahl von Haus aus. Sie übernehmen UITextInput nur dann selbst, wenn Sie eigenen Text rendern, etwa eingescannte Seiten oder anspruchsvolle Typografie, wo diese Systemverhalten verloren gehen1.

Wann sollte ein benutzerdefiniertes Steuerelement das Adjustable-Merkmal und wann benutzerdefinierte Aktionen verwenden?

Verwenden Sie das .adjustable-Merkmal mit accessibilityAdjustableAction für einachsige Werte, bei denen Inkrement und Dekrement sinnvoll sind, etwa einen Slider. Verwenden Sie benutzerdefinierte Aktionen (den Modifier accessibilityAction), wenn eine Achse nicht genügt, etwa bei einem zweidimensionalen Pad, oder wenn Sie diskrete Vorgänge bereitstellen möchten, die VoiceOver beim Namen vorliest. Das Equalizer-Pad der Session verwendet genau deshalb vier benutzerdefinierte Aktionen (nach oben/rechts/unten/links), weil das Adjustable-Merkmal nur eine Richtung abdeckt2.

Was ist Direct Touch und wann sollte ich es verwenden?

Direct Touch (das Merkmal allowsDirectInteraction, in SwiftUI über .accessibilityDirectTouch angewendet) kennzeichnet einen Bereich so, dass Berührungen direkt an Ihr Steuerelement gelangen, statt von VoiceOver verarbeitet zu werden, sodass Menschen jede vom Steuerelement unterstützte Geste nutzen können. Verwenden Sie es bei gestenlastigen Steuerelementen, bei denen die Durchreich-Geste schlecht passt, und kombinieren Sie es mit .requiresActivation, um versehentliche Auslösungen zu verhindern. Bieten Sie stets eine nicht-gestische Ausweichlösung an, etwa benutzerdefinierte Aktionen, für Menschen, die keine Direct-Touch-Gesten ausführen können2.

Wie hilft barrierefreier Text Funktionen über VoiceOver hinaus?

Dieselbe Arbeit zahlt sich bei „Bildschirm sprechen” aus und, seit iOS 26, beim Bedienungshilfen-Reader, der die Inhalte einer App in einer auf leichteres Lesen abgestimmten Darstellung öffnet. Die Umsetzung der Praktiken für Textnavigation, Seitenwechsel und UITextInput, die die Lese-Session behandelt, verbessert alle drei Erlebnisse aus ein und demselben Satz an Änderungen1.

Weiterführende Lektüre

Quellen


  1. Apple, WWDC26-Session 219, „Enhance the accessibility of your reading app.” developer.apple.com/videos/play/wwdc2026/219. Quelle für die Übernahme von UITextInput durch System-Textansichten (UITextView, TextEditor, Text mit Auswahl, NSTextView); die iOS-18-APIs accessibilityNextTextNavigationElement/accessibilityPreviousTextNavigationElement und den iOS-27-SwiftUI-Modifier accessibilityLinkedGroup (AppKit: accessibilitySharedTextUIElements); causesPageTurn mit accessibilityScroll; die Textauswahl-Aktion über accessibilityCustomActions mit der Kategorie „edit”; die vollständige Übernahme von UITextInput für eigenen Text (selectionRects, textInRange, UITextInputStringTokenizer) samt optionalem UITextInteraction; sowie den iOS-26-Bedienungshilfen-Reader. 

  2. Apple, WWDC26-Session 220, „Refine accessibility for custom controls.” developer.apple.com/videos/play/wwdc2026/220. Quelle für die Prinzipien Zweck/Wert/Aktionen/Rückmeldung; das Kaffeespender-Steuerelement mit accessibilityLabel, accessibilityValue, dem .adjustable-Merkmal und accessibilityAdjustableAction; die Durchreich-Geste am accessibilityActivationPoint mit gedrosselten Ankündigungen (Wertänderung plus 0,3 Sekunden verstrichen); den Modifier accessibilityAction für das Equalizer-Pad; sowie Direct Touch über allowsDirectInteraction (.accessibilityDirectTouch) mit .requiresActivation und .silentOnTouch für das virtuelle Katzen-Steuerelement, samt dem Hinweis auf die nicht-gestische Ausweichlösung. 

Verwandte Beiträge

SwiftUI-Performance und -Interop in iOS 27

Wie SwiftUI in iOS 27 das Scrollen in Lazy Stacks, GPU-Shader-Effekte und die Interop mit AppKit/UIKit handhabt – auf Gr…

16 Min. Lesezeit

Was ist neu in SwiftUI für iOS 27

iOS 27 überarbeitet SwiftUI-Listen, -Dokumente, -Toolbars und -Fehler: Ziehen zum Neuordnen, ein les-/schreibbares Dokum…

21 Min. Lesezeit

Der Agent-Stack für Design Engineers

Design Engineers brauchen eine Agent-Infrastruktur, die visuelle Konsistenz, typografische Disziplin, Farb-Compliance un…

11 Min. Lesezeit