Wenn Sie ein Produkt für den Massenmarkt entwickeln, verwenden es höchstwahrscheinlich Menschen mit Sehbehinderung. Wenn Sie benutzerfreundliche Benutzeroberflächen erstellen möchten, müssen Sie dies bequem für alle Kunden tun, auch für Personen mit Sehbehinderung. Ich denke, wir vergessen es oft. Und es ist Zeit, das Problem zu beheben.

Ich habe bei einer Suche im App Store die Abfrage „Pizza Delivery“ eingegeben, die ersten 24 Anwendungen heruntergeladen und überprüft, welche davon eine Schnittstelle für Menschen mit Sehbehinderung bietet.
2 von 24 . Und einer der beiden hat es anscheinend aus Versehen getan: Mit zunehmender Schriftgröße „schwebt“ die gesamte Benutzeroberfläche und die Verwendung wird nur noch schwieriger. Es ist traurig.
Jeden Monat nutzen 550.000 Menschen die Dodo Pizza iOS-App. Selbst wenn 1% unserer Benutzer eine vergrößerte Schrift haben, sind es 5500 Personen, die sich mit unserer Anwendung nicht wohl fühlen. Wir werden es korrigieren.
Unterstützung für dynamische Typen hinzufügen
- Wir verwenden dynamische Systemtextstile anstelle von statischen.
- Aktivieren Sie optional das Kontrollkästchen Schrift automatisch anpassen auf Beschriftungen in Storyboards. Oder wenn die Beschriftung in der Schaltfläche oder durch den Code erstellt wird, klopfen wir auf den Parameter
adjustsFontForContentSizeCategory
. - Wir bringen der Benutzeroberfläche bei, sich auf verschiedene Schriftgrößen auszudehnen:
- Wir verwenden die automatische Berechnung der Zellgrößen, wo wir können.
- Wo wir nicht können - erhalten wir die aktuellen Einstellungen für die Schriftgröße und reagieren auf Änderungen in der traitCollectionDidChange
Methode. - Wir bekommen eine Schnittstelle, die nicht zu benutzen ist.

Wir ändern die Schnittstelle, damit sie verwendet werden kann
Wir rollen zurück und überlegen, wie wir alles gut machen können.
Verwenden Sie den Platz im Menü ordnungsgemäß
Jetzt gibt es viel leeren Raum unter dem Pizzabild. Versuchen wir, ein Bild über den Namen zu setzen: Auf diese Weise wird es größer und der leere Raum verschwindet. Dazu
UIStackView
wir den Bild- und
UIStackView
mit allem anderen in
UIStackView
und
UIStackView
dann bei Bedarf die Richtung der
UIStackView
.

Wir haben keine Trennzeichen zwischen den Menüelementen, weshalb bei großen Abmessungen die Zellen „zusammenkleben“ und der Pizza-Preis zu nahe am Bild der nächsten Pizza liegt. Versuchen wir, ein Trennzeichen hinzuzufügen.

Nicht das. Erstens sieht es so lala aus. Zweitens wird es für Menschen mit Sehbehinderung schwer zu sehen sein. Auch wenn von grau nach schwarz neu gestrichen.
Wir entfernen es zurück und versuchen nur, das Internet zwischen den Zellen zu vergrößern.

Nun dann.
Zwischensumme: Verwenden Sie mehr Platz, die Augen springen weniger von Zeile zu Zeile, das Lesen ist einfacher geworden.
Wir verbessern das Dehnen und Entfernen
Jetzt können Sie die Breite der Schaltfläche zum Hinzufügen zum Warenkorb erhöhen, andernfalls schwebte sie nach links und befindet sich nicht unter Ihrem Finger, obwohl rechts viel Platz frei ist. Sie können es natürlich einfach nach rechts verschieben, aber dann ist es für Linkshänder unpraktisch, und im Allgemeinen sollten wir besser gestikulieren als unkomprimiert. Und wir werden den Strich dicker machen, und jetzt stimmt er nicht mit der Schriftart überein.

Ich schaue mir das alles an und verstehe, dass das Pizza-Foto natürlich sehr groß ist. Versuchen wir es zu verstecken, vielleicht ohne Bilder, die Sie leben können.

Im Allgemeinen hat ein Menü ohne Fotos nicht viele Informationen verloren, aber jetzt stört fast immer ein Menüpunkt den Bildschirm eines iPhone 6S. Aber es ist weniger attraktiv geworden, Drool fließt beim Scrollen nicht. So. Lassen wir es vorerst so, überlegen Sie es sich gut und geben Sie das Bild vielleicht später zurück.
Vergessen Sie nicht, "live" zu überprüfen
Jetzt Kategorien. Im Allgemeinen stellte sich heraus, dass es bereits beim ersten Ansatz erträglich war. Schalten Sie einen neuen ein.

Ich habe versucht, durch das Menü zu blättern und zwischen den Kategorien zu wechseln. Trotzdem stellte sich heraus, dass alles in Aktion auseinander fällt. Beim Scrollen durch das Menü wechseln die Kategorien automatisch und ziehen bei so großen Pins zu viel Aufmerksamkeit auf sich.
Ersetzen wir die
UICollectionView
durch eine Schaltfläche, die das
UIActionSheet
.

Voooot. Jetzt können Sie im oberen Bereich die Stadt, die Lagerbestände, die Adresse und den Aktionscode anzeigen.
Vergessen Sie nicht sehr lange Schlangen
Lassen Sie uns zuerst eine Auswahl der Stadt treffen. Die Schriftart in der Schaltfläche ist nicht kompliziert, aber es ist interessant, den "Dreiecken" beizubringen, mit der Schriftart zu wachsen. In unserem Fall wurde das Dreieck zu einem Symbol in der Schaltfläche gemacht, das über
CGAffineTransform
nach rechts
CGAffineTransform
. Eine andere Möglichkeit besteht darin,
NSAttributedString
aus dem Text und dem Dreiecksymbol zu sammeln und dann alles der Schaltfläche
NSAttributedString
. Um das Symbol zu normalisieren, können Sie ein Vektorbild verwenden, das sich unbedingt in Assets mit dem Häkchen "Vektordaten beibehalten" befinden muss.

Das Symbol des Dreiecks ist schwarz und wird durch den Code weiß gestrichen. Und aus irgendeinem Grund treten bei der Standardtextgröße Artefakte in Form von schwarzen Randtafeln auf. Es ist lustig Nicht sehr. Er wurde geheilt, indem er ein Symbol anbrachte, das ursprünglich weiß war.
Jetzt strecken wir die Dodo-Rubel, alles ist einfach:

Und jetzt ist die Frage: Was wird passieren, wenn der Name der Stadt lang wird und wir viele Dodo-Rubel haben? Theoretisch müssen Sie den Namen der Stadt kürzen. Erinnern Sie sich, was ich über die zweite Option zum Hinzufügen eines solchen Symbols zu einer Schaltfläche über
NSAttributedString
? Ich habe es versucht und jetzt gibt es ein Problem, dass beim Reduzieren des Titels das Dreieckssymbol verschwindet, da es jetzt Teil des Titels ist. Stosh. Wir müssen die Logik des Verschiebens des Symbols durch Transformationen zurückgeben.
Wenn Sie eine bequeme Möglichkeit kennen, das Symbol in der Schaltfläche nach rechts zu verschieben und zusammen mit der Schriftart in der Kopfzeile zu skalieren, verwerfen Sie es bitte in den Kommentaren.
Cram in
Endlich Aktien. Hier muss man sich setzen und nachdenken. Der Titel kann lang sein und passt auch jetzt manchmal nicht in eine Zeile. Bei einer großen Größe wird er überhaupt nicht gut passen. Wenn Sie das obere orangefarbene Gummi herstellen und zulassen, dass der Titel der Aktion in einer großen Größe mehrere Zeilen einnimmt, nimmt der obere Block selbst auf großen iPhones die Hälfte des Bildschirms ein, und Sie müssen sich nicht an 4S erinnern. Dies ist nicht der Fall. Sie können mit einem Layout innerhalb des Aktionsfelds spielen: Machen Sie das Bild quadratisch und nehmen Sie die freie Stelle als Überschrift. Die Bilder für Bestände sind jedoch an ein bestimmtes Format angepasst und werden in einem anderen Format nicht korrekt angezeigt. Das ist unmöglich.
Kompliziert
Also, aber Sie können die Bilder wieder komplett entfernen und den ganzen Platz mit einer Überschrift einnehmen.

Ja, das ist es. Hände jucken, um den Hintergrund unter dem Titel der Aktion einzufärben, dies beeinträchtigt jedoch die Lesbarkeit. Und wir versuchen es zu verbessern. Wir malen also nichts und gehen zu den verbleibenden zwei Schaltflächen über die Adresse und die Aktionscodes über.
Wir arbeiten mit strengen Einschränkungen
Die Überschriften in diesen Schaltflächen sind nicht reduzierbar. Wenn sie jedoch nicht verkleinert werden, kriechen die Tasten aufeinander zu. Und ja, Sie können diese Schaltflächen nicht ausblenden.
Als ich den Vorrat überarbeitete, wollte ich die Höhe des oberen orangefarbenen Feldes nicht erhöhen. Es scheint zu müssen. Es ist gut, dass sie es zu diesem Zeitpunkt nicht erhöht haben, sonst würde es jetzt Aduha geben. Im Allgemeinen werde ich für jede Schaltfläche eine Zeile auswählen.

Ufff, das war's. Was die ausgeschalteten Fotos im Menü betrifft, bin ich mir immer noch nicht sicher. Alternativ können Sie nur die Hälfte der Pizzabilder anstelle eines ganzen Kreises anzeigen, aber wir haben gerade die Hälfte der Pizza auf der Speisekarte, sodass dies nicht funktioniert und wir die Benutzer verwirren können.
Vergleichen wir den ersten Ansatz mit dem Endergebnis:

Vergleichen Sie nun das Vorher und Nachher mit einer Simulation von Sehstörungen:

Haben Sie keine Angst, die Schnittstelle und die Steuerelemente zu ändern. Es ist nichts Falsches daran, wenn jemand eine andere Schaltfläche oder beispielsweise einen Schieberegler sieht. Und es ist nicht tödlich, wenn jemand etwas nicht sieht oder wenn der Titel anders ist.
Und wir haben den UITabBarController
nicht berührt, da bei einer großen Textgröße das Symbol und der Titel der Registerkarte UITabBarController
, wenn iOS die Änderung der Lautstärke anzeigt.
Wir zeigen, wie alles im Inneren funktioniert
Jede logische UI-Komponente in der Dodo Pizza iOS-Anwendung ist einem separaten
UIViewController
. Jeder dieser Controller verfügt über eine
UIView
, die einer separaten Datei zugeordnet ist. Mehr dazu lesen Sie in unseren Artikeln:
Controller, sei ruhig! Wir nehmen den Code in UIView herausZwiebelkontrolleur. Wir zerlegen Bildschirme in TeileDas Entfernen logischer UI-Komponenten in einen separaten
UIViewController
das Ändern von Schnittstellen in verschiedene Zustände erheblich vereinfacht. Wir empfehlen, dass Sie diesen Ansatz ausprobieren, auch wenn Sie keine Unterstützung für Dynamic Type hinzufügen möchten. Es ist einfacher, den Status von Bildschirmen zu steuern: Reagieren Sie auf Änderungen an Berechtigungen, Rechten, Rollen usw.
Also. Wir fügen eine zusätzliche Ebene zwischen einer solchen UI-Komponente und ihrem übergeordneten Container hinzu. Wir haben es
StateViewController
.

Der Controller mit dem Menü integriert den Status-Controller und bettet bereits den
collection
oder Tastencontroller ein.
Dieser
StateViewController
zeigt diese oder jene UI-Komponente je nach Situation an.
Dazu muss
StateViewController
kennen und gegebenenfalls wechseln.
In diesem Beispiel
StateViewController
der
StateViewController
die Auswahl der Kategorien im Menü von Sammlung zu Schaltfläche und umgekehrt um. Und im Fall einer „normalen“ Anzeige und im Fall einer Anzeige für sehbehinderte Personen sollte der Selektor in der Lage sein, die gleichen Dinge zu tun:
- Liste der Kategorien anzeigen.
- Markieren Sie die ausgewählte Kategorie.
- Kategorieliste aktualisieren.
- Berichten Sie, dass die Kategorie "ausgestiegen" ist.
Fühlen Sie diesen wunderbaren Geruch von frischen kleinen Stämmen? Und nein, dies ist ein Team von Pizza mit mobiler API. 5 Minuten Pause.
2 Scheiben später"... Nun, wir verpacken unsere Komponenten so, um Kategorien in den Protokollen auszuwählen, UND SIE SIND SOFORT!"
Tipp: Starten Sie den Eingabehilfen-Inspektor, um auf einfache Weise zu überprüfen, wie die Benutzeroberfläche auf Änderungen in den Einstellungen für dynamische Kacheln reagiert. Klicken Sie dazu im geöffneten Xcode auf Xcode → Entwicklertool öffnen → Eingabehilfeninspektor, wählen Sie den Simulator im Gerät aus und wechseln Sie zur letzten Registerkarte
Ein weiterer Hinweis: Nehmen Sie die Dynamo-Taip-Steuerung auf dem iPhone (nicht auf dem Simulator) in das Control Center, um die Textgröße einfach und schnell zu ändern. Gehen Sie dazu auf einem iPhone zu Einstellungen → Control Center → Steuerelemente anpassen und fügen Sie die Textgröße hinzu.
Wir haben den üblichen Kategorieselektor
CategoriesCollectionViewController
und für Sehbehinderte
CategoriesButtonViewController
. Ihr gemeinsames Protokoll heißt
CategoriesPickerProtocol
. Der allgemeine Statuscontroller ist
CategoriesStateViewController
.
Wir beschreiben die möglichen Zustände in unserem
CategoriesStateViewController
:
private enum State { case collection, button }
Wir bringen ihm bei, den gewünschten Controller für jeden Zustand anzuzeigen:
private var state: State = .collection { didSet { if state != oldValue { updateViewController(for: state) } } } private func updateViewController(for state: State) { let viewController = self.viewController(for: state) self.updateController(with: viewController) } private func viewController(for state: State) { switch state { case .collection: return CategoriesCollectionViewController.instantiateFromStoryboard() case .button: return CategoriesButtonViewController.instantiateFromStoryboard() } }
instantiateFromStoryboard()
- Eine Methode von einer selbstgeschriebenen Erweiterung zu einem View-Controller. Erstellt eine Controller-Instanz aus Storyboards, wenn sie denselben Namen haben. Der Code befindet sich im Quellcode am Ende des Artikels.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) self.updateStateToCurrentContentSize() } private func updateStateToCurrentContentSize() { let contentSize = self.traitCollection.preferredContentSizeCategory self.updateState(to: contentSize) } private func updateState(to contentSize: UIContentSizeCategory) { self.state = contentSize.isAccessibilityCategory ? .button : .collection }
Wir beschreiben das
CategoriesPickerProtocol
Protokoll und fügen gleichzeitig zwei weitere Protokolle hinzu: für den Delegaten und für die Datenmenge.
protocol CategoriesPickerProtocol where Self: UIViewController { var datasource: CategoriesDatasource? { get set } var delegate: CategoriesDelegate? { get set } func select(_ category: ProductCategoryModule.ProductCategoryViewModel) func updateCategories() var selectedCategory: ProductCategoryModule.ProductCategoryViewModel? { get } } protocol CategoriesDatasource: class { var categories: [ProductCategoryModule.ProductCategoryViewModel] { get } func index(of category: Product.ProductCategory) -> Int } protocol CategoriesDelegate: class { func productCategoriesView(_ categoriesPicker: CategoriesPickerProtocol, didSelect category: ProductCategoryModule.ProductCategoryViewModel) }
Es macht keinen Sinn, die Implementierung zu zeigen. Es ist nur so, dass jeder Piker die Kategorien anzeigt und Änderungen nach oben meldet.
Ein detailliertes Beispiel für die Verwendung von State Controllern für Dynamic Taype finden Sie in meinem
Repo auf GitHub .
→
Wir expandieren übrigens