2015-01-06 5 views
30

Ich versuche herauszufinden, was genau anders passiert, wenn Sie eine UIAccessibilityLayoutChangedNotification und eine UIAccessibilityScreenChangedNotification veröffentlichen. Von dem, was ich sehen kann, kann ich sie überall austauschbar verwenden und nichts anderes passiert.Der tatsächliche Unterschied zwischen UIAccessibilityLayoutChangedNotification und UIAccessibilityScreenChangedNotification?

Die Apple-Dokumentation sagt einfach LayoutChanged zu verwenden, wenn (zum Beispiel) ein Element ein- oder ausgeblendet wurde und ScreenChanged wenn die gesamten Bildschirm wechselt zu verwenden, aber ich bin daran interessiert, was sie tun, wenn ich diese Informationen zur Verfügung stellen, und was ich anders sehen sollte, wenn ich das eine oder das andere benutze.

Kann jemand die Implementierungsunterschiede zwischen den beiden klar erklären?

Antwort

36

Diese beiden Benachrichtigungen gelten für dynamischen Inhalt in Ansichten und die Übermittlung dieser Änderungen an VoiceOver für Benutzer von Bildschirmleseprogrammen. Abgesehen von ihrem Standardverhalten und dem albernen kleinen Boop-Piep für ScreenChange-Benachrichtigungen gibt es kaum einen Unterschied zwischen diesen beiden Benachrichtigungen.

In beiden Fällen ist das Argument

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, arg); 

Stellt eine Zeichenfolge ausgelesen werden, oder ein auf dem Bildschirm Element, das Voiceover seinen Fokus verschieben. Bei dramatischen Kontextänderungen ist es wichtig, den Fokus auf einen sinnvollen Ort zu richten oder zu melden, dass solche Änderungen stattgefunden haben. Beide Ansätze sind aus Sicht der Zugänglichkeit akzeptabel, obwohl ich Ansätze vorziehe, die möglichst wenig Änderungen mit sich bringen. Bei einfachen Layoutänderungen ist es fast immer am besten, die Kontextänderung anzukündigen und den Fokus dort zu belassen, wo er war. Manchmal ist jedoch das Element, das die Kontextänderung verursacht hat, verborgen, und dann ist es offensichtlich notwendig, Voiceover zu verwenden, um neuen Inhalt hervorzuheben, da das Standardverhalten in diesem Fall nicht definiert oder vielleicht deterministisch ist, aber durch ein Framework bestimmt wird, das absolut nichts weiß über deine App!

Der Unterschied zwischen den beiden Ereignissen besteht darin, dass sie beide genau dasselbe tun. Wenn Sie Null an die UIAccessibilityLayoutChangedNotification liefern, ist es als ob Sie nichts getan haben.Wenn Sie dem UIAccessibilityScreenChangedNotification ein Null-Argument übergeben, sendet es den Fokus an das erste UIObject in Ihrer Ansichtshierarchie, das als accessibilityElement markiert ist, sobald alle Änderungen der Ansichtshierarchie und die Zeichnungen abgeschlossen sind.

UIAccessibilityLayoutChangedNotification

Ein guter Anwendungsfall Beispiel für UIAccessibilityLayoutChangedNotification für dynamische Formulare ist. Sie möchten Benutzern mitteilen, dass basierend auf Entscheidungen, die sie im Formular getroffen haben, neue Optionen verfügbar sind. Wenn Sie beispielsweise in einem Formular auswählen, dass Sie ein Veteran sind, können zusätzliche Bereiche des Formulars angezeigt werden, um mehr Eingaben zu ermöglichen. Diese Bereiche wurden jedoch möglicherweise für andere Benutzer ausgeblendet, die sich nicht um sie kümmern. So könnte man den Fokus auf diese Elemente nach Interaktion mit dem Benutzer verschieben:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, firstNewFormElement); 

Welche Fokus auf das vorgesehene Element verschieben würde, und verkündet es accessibilityLabel ist.

Oder sie nur sagen, dass die neuen Formularelemente sind:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, @"Veterans form elements available"); 

Welche konzentrieren lassen, wo es ist, aber würde ankündigen Voiceover „Veterans bilden Elemente verfügbar“.

Hinweis: Dieses spezielle Verhalten ist auf meinem iPad (8.1.2) abgehört.

Oder schließlich können Sie dies tun:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); 

die absolut nichts tut :). Im Ernst, ich denke nicht einmal, dass das a11y Framework-Backend sich darum kümmert. Diese spezielle Codezeile ist eine völlige Verschwendung!

UIAccessibilityScreenChangedNotification

Ein guter Anwendungsfall Beispiel für die UIAccessibilityScreenChangedNotification angepasst ist Situationen Tabbed Browsing. Wenn sich der gesamte Bildschirm mit Ausnahme Ihres Navigationsbereichs ändert. Sie möchten Voiceover wissen lassen, dass sich im Wesentlichen der gesamte Bildschirm geändert hat, NICHT jedoch das erste Element (Ihre erste Registerkarte) fokussieren, sondern das erste Inhaltselement fokussieren.

Welche würde den "Boop Beep" Sound spielen und dann den Fokus auf knapp unterhalb der globalen Navigationsleiste verschieben. Oder Sie könnten dies tun:

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, @"You're on a new tab"); 

, die für die neuen Registerkarte warten würde zu laden, spielen den „Piep boop“ Ton, ankündigt „Du bist auf einen neuen Tab“ in Voice-over, dann verschiebt Fokus auf den ersten Element auf dem Bildschirm, dann kündigen Sie die accessibilityLabel für dieses Element an. (PHEW! Das ist eine Menge! Dies ist für Screenreader-Benutzer jarring. Vermeiden Sie dieses Szenario, es sei denn, absolut notwendig).

Und schließlich können Sie natürlich tun:

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);  

Welche entspricht:

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstA11yElement); 

beide die „Piep boop“ Ton spielen, verschieben Voiceover Fokus auf das erste Element auf dem Bildschirm, und kündigen Sie es dann an.

Schließlich

In einem Kommentar jemand erwähnt Caching und ich in meiner Antwort über Dinge gelegentlich Kommentar über das A11y Backend kann oder auch nicht. Es ist zwar möglich, dass es eine Backend-Magie gibt, aber ich glaube nicht an diese Umstände, das Backend interessiert sich überhaupt nicht. Der Grund, warum ich das sage ist, weil:

Wenn Sie jemals das UIAccessibilityContainer Protokoll verwendet haben, können Sie beobachten, wie Ihr Container von Ansichten abgefragt wird. Es findet kein Caching statt. Auch die Eigenschaft accessibilityElementCount10 wird immer dann gepingt, wenn VoiceOver den Fokus auf ein neues AccessibilityElement in Ihrem Container ändert. Dann wird überprüft, auf welchem ​​Element es sich befindet, nach dem nächsten Element gefragt und so weiter. Es ist im Kern auf dynamische Situationen ausgelegt. Wenn Sie nach der Interaktion ein neues Element in Ihren Container einfügen würden, würde es immer noch alle diese Abfragen durchlaufen und es wäre in Ordnung! Wenn Sie darüber hinaus die Eigenschaften des UIAccessibility-Protokolls überschreiben, um dynamische Hinweise und Beschriftungen bereitzustellen, können Sie außerdem sehen, dass diese Funktionen jedes Mal aufgerufen werden! Daher glaube ich, dass das A11y-Framework-Backend ABSOLUT ZERO-Informationen aus diesen Benachrichtigungen liefert. Die einzige Information, die VoiceOver benötigt, um seine Aufgabe zu erledigen, ist, dass es sich derzeit um ein Accessibility-Element handelt, und dieses Element Accessibility Container. Die Benachrichtigungen dienen lediglich dazu, Ihre App für VoiceOver-Benutzer besser nutzbar zu machen.

Stellen Sie sich vor, dies wäre nicht der Fall, wie oft Safari diese Benachrichtigungen posten würde !!!! :)

Diese bestimmten Aussagen können nur von jemandem mit Backendwissen des Frameworks bestätigt werden, der mit dem Code arbeitet und als Vermutung betrachtet werden sollte. Es könnte sein, dass dies in hohem Maße versions-/implementierungsabhängig ist. Definitiv offen für Diskussionen zu diesen Punkten! Der Rest dieses Beitrags ist ziemlich konkret.

Zu Ihrer Information

Die meisten davon stammen aus der Erfahrung mit den Rahmenbedingungen zu arbeiten, aber hier ist eine nützliche Referenz, wenn Sie weiter graben wollen.

https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility

https://developer.apple.com/documentation/uikit/uiaccessibilitylayoutchangednotification

https://developer.apple.com/documentation/uikit/uiaccessibilityscreenchangednotification

Und schließlich ein Open-Source-Repo der dumme kleine app, die ich zusammen all dieses Zeug auf dem Prüfstand. Diese

https://github.com/chriscm2006/IOS-A11y-Api-Test

+3

Es genagelt. Gute Idee, gegen 'UIAccessibilityContainer' zu testen. – Justin

+3

Perfekt. Vielen Dank. Ich stimme @Justin zu. Ich habe auch den Fehler reproduziert, den Sie erwähnt haben, und ein Radargerät abgelegt. –

+2

Große Antwort. Ich stimme dem Thema Caching nur wenig zu. Ich bin mir 100% sicher, dass irgendwo irgendwo ein Cache ist. Erläuterung: Ich habe einige Tests gegen 'UIAccessibilityContainer' durchgeführt und wie Sie sagen, werden die Containermethoden aufgerufen, wenn der Fokus verschoben wird. ABER, was auch immer die Container-Protokoll-Methoden zurückgeben, in einigen Situationen liest Voiceover immer falsche Werte, wenn Sie nicht ausdrücklich eine Layout-/Bildschirmänderungsbenachrichtigung posten. So gibt es Caching unter der Haube.Es kann nicht nur Elemente zwischenspeichern, aber es speichert (Element, Position) Paare oder etwas um diese Zeilen. –

-1

UIAccessibilityScreenChangedNotification bedeutet, dass der gesamte Bildschirm geändert wurde und VoiceOver zurückgesetzt werden sollte.

UIAccessibilityLayoutChangedNotification soll anzeigen, dass sich ein oder mehrere, aber nicht alle Elemente auf dem Bildschirm geändert haben.

Wenn sich Ihre Benutzeroberfläche dramatisch ändert. Normalerweise, wenn ein Benutzer in einen anderen Teil Ihrer App wechselt (zu einem anderen Bildschirm navigiert). VoiceOver benachrichtigt den Benutzer mit einem Ton, und es löscht seine Zwischenspeicher und andere Vorbereitungen, um mit einer neuen Reihe von Eingabedaten umzugehen. Es weist VoiceOver darauf hin, dass sich der Bildschirm geändert hat und dass möglicherweise neue Elemente auf dem Bildschirm erscheinen, sodass VoiceOver den Index der Barrierefreiheitselemente neu erstellt.

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); 

Wenn ein Teil Ihrer Änderungen an der Benutzeroberfläche, aber der Benutzer hat zu einem ganz anderen Teil Ihrer App nicht unbedingt springt. (Beispiel: In der iTunes Store-App wird durch Tippen auf das Preisschild ($ 0,99 usw.) neben einem Titel ein "Kaufen" -Button angezeigt.) Diese Benachrichtigung weist VoiceOver an, den aktuellen Status aller verfügbaren Objekte erneut zu lesen sind auf dem Bildschirm und dadurch herauszufinden, was sich geändert hat und informiert den Benutzer über diese Änderungen. VoiceOver wird darauf hingewiesen, dass sich das Layout geändert hat und dass der aktuelle Index veraltet ist, da sich die Elemente auf dem Bildschirm selbst neu angeordnet haben.

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); 
+3

sind fair Beispiele, aber sie haben nicht die Frage beantworten. Können Sie Beweise dafür liefern, dass A) VoiceOver "seine Caches löscht" als Reaktion auf eine Bildschirmwechselbenachrichtigung, aber keine Benachrichtigung über eine Layoutänderung und dass B) Voiceover "den Benutzer mit einem Ton" als Reaktion auf Bildschirmänderungen benachrichtigt, aber nicht Layoutänderungen? – Justin

Verwandte Themen