Grundsätzlich möchte ich, dass meine Unteransichten je nach Ausrichtung des iPad (Hochformat oder Querformat) mithilfe der in xcode 6 eingeführten Größenklassen unterschiedlich positioniert werden. Ich habe zahlreiche Tutorials gefunden, in denen erläutert wird, wie verschiedene Größenklassen für Iphones im Hoch- und Querformat auf dem IB verfügbar sind Es scheint jedoch keine zu geben, die einzelne Quer- oder Hochformatmodi für das iPad auf IB abdecken. Kann jemand helfen?
objective-c
ios8
size-classes
adaptive-ui
neelIVP
quelle
quelle
Antworten:
Es scheint Apples Absicht zu sein, beide iPad-Ausrichtungen als gleich zu behandeln - aber wie einige von uns feststellen, gibt es sehr legitime Designgründe, das UI-Layout für iPad Portrait im Vergleich zu iPad Landscape variieren zu wollen.
Leider scheint das aktuelle Betriebssystem diese Unterscheidung nicht zu unterstützen ... was bedeutet, dass wir wieder die Einschränkungen des automatischen Layouts in Code oder ähnlichen Problemumgehungen bearbeiten, um das zu erreichen, was wir idealerweise mit der adaptiven Benutzeroberfläche kostenlos erhalten sollten .
Keine elegante Lösung.
Gibt es nicht eine Möglichkeit, die Magie, die Apple bereits in IB und UIKit eingebaut hat, zu nutzen, um eine Größenklasse unserer Wahl für eine bestimmte Ausrichtung zu verwenden?
~
Als ich allgemeiner über das Problem nachdachte, wurde mir klar, dass 'Größenklassen' einfach Möglichkeiten sind, mehrere in IB gespeicherte Layouts zu adressieren, damit sie zur Laufzeit nach Bedarf aufgerufen werden können.
Tatsächlich ist eine 'Größenklasse' nur ein Paar von Aufzählungswerten. Von UIInterface.h:
Also unabhängig davon , was Apple hat beschlossen, nennt diese verschiedenen Variationen, im Grunde sind sie nur ein Paar von ganzen Zahlen als eindeutige Kennung der Art verwendet, ein Layout von einem anderen zu unterscheiden, in IB gespeichert.
Angenommen, wir erstellen in IB ein alternatives Layout (unter Verwendung einer nicht verwendeten Größenklasse) - beispielsweise für iPad Portrait ... gibt es eine Möglichkeit, das Gerät zur Laufzeit nach Bedarf die von uns gewählte Größenklasse (UI-Layout) verwenden zu lassen ?
Nachdem ich verschiedene (weniger elegante) Ansätze für das Problem ausprobiert hatte, vermutete ich, dass es eine Möglichkeit gibt, die Standardgrößenklasse programmgesteuert zu überschreiben. Und es gibt (in UIViewController.h):
Wenn Sie also Ihre View-Controller-Hierarchie als untergeordneten View-Controller verpacken und zu einem übergeordneten View-Controller der obersten Ebene hinzufügen können, können Sie das untergeordnete Element unter der Bedingung überschreiben, dass es sich um eine andere Größenklasse als die Standardgröße handelt vom Betriebssystem.
Hier ist eine Beispielimplementierung, die dies im übergeordneten Ansichtscontroller tut:
Als schnelle Demo, um zu sehen, ob es funktioniert hat, habe ich benutzerdefinierte Beschriftungen speziell zu den Versionen 'Regular / Regular' und 'Compact / Regular' des untergeordneten Controller-Layouts in IB hinzugefügt:
Und so sieht es beim Laufen aus, wenn sich das iPad in beiden Richtungen befindet:
Voila! Benutzerdefinierte Größenklassenkonfigurationen zur Laufzeit.
Hoffentlich macht Apple dies in der nächsten Version des Betriebssystems unnötig. In der Zwischenzeit ist dies möglicherweise ein eleganterer und skalierbarer Ansatz als das programmgesteuerte Durcheinander mit Einschränkungen beim automatischen Layout oder andere Manipulationen im Code.
~
EDIT (6/4/15): Bitte beachten Sie, dass der obige Beispielcode im Wesentlichen ein Proof of Concept ist die Technik zu demonstrieren. Sie können sich jederzeit an Ihre spezifische Anwendung anpassen.
~
EDIT (24.07.15): Es ist erfreulich, dass die obige Erklärung dazu beiträgt, das Problem zu entmystifizieren. Obwohl ich es nicht getestet habe, sieht der Code von mohamede1945 [unten] aus praktischen Gründen wie eine hilfreiche Optimierung aus. Probieren Sie es einfach aus und teilen Sie uns Ihre Meinung mit. (Der Vollständigkeit halber lasse ich den obigen Beispielcode unverändert.)
quelle
UITraitCollection
ist ausreichend optimiert undoverrideTraitCollectionForChildViewController
wird selten genug aufgerufen, sodass es kein Problem sein sollte, die Breitenprüfung durchzuführen und sie dann zu erstellen.Als Zusammenfassung der sehr langen Antwort von RonDiamond. Alles, was Sie tun müssen, ist in Ihrem Root View Controller.
Ziel c
Schnell:
Verwenden Sie dann in Storyborad die kompakte Breite für Hochformat und die reguläre Breite für Querformat.
quelle
- (UITraitCollection *)traitCollection
stattoverrideTraitCollectionForChildViewController
. Auch die Einschränkungen sollten mit den Merkmalssammlungen übereinstimmen, also wC (hAny).Das iPad hat die Eigenschaft "normale" Größe sowohl für horizontale als auch für vertikale Dimensionen, wobei kein Unterschied zwischen Hoch- und Querformat besteht.
Diese Größenmerkmale können in Ihrem benutzerdefinierten
UIViewController
Unterklassencode über folgende Methode überschrieben werdentraitCollection
:Dies gibt dem iPad die gleichen Größenmerkmale wie dem iPhone 7 Plus. Beachten Sie, dass andere iPhone-Modelle unabhängig von ihrer Ausrichtung im Allgemeinen die Eigenschaft "kompakte Breite" (anstelle der regulären Breite) aufweisen.
Durch die Nachahmung des iPhone 7 Plus auf diese Weise kann dieses Modell als Ersatz für das iPad im Interface Builder von Xcode verwendet werden, bei dem keine Anpassungen im Code bekannt sind.
Beachten Sie, dass die geteilte Ansicht auf dem iPad möglicherweise andere Größenmerkmale als der normale Vollbildbetrieb verwendet.
Diese Antwort basiert auf dem in diesem Blogbeitrag verfolgten Ansatz mit einigen Verbesserungen.
Update 2019-01-02: Aktualisiert, um die zeitweise verborgene Statusleiste in der iPad-Landschaft und das mögliche Trampeln von (neueren) Merkmalen in zu beheben
UITraitCollection
. Es wird auch darauf hingewiesen, dass in der Apple-Dokumentation tatsächlich davon abgeraten wird, diese zu überschreibentraitCollection
, sodass sich in Zukunft möglicherweise Probleme mit dieser Technik herausstellen.quelle
traitCollection
Eigenschaft schreibgeschützt ist: developer.apple.com/documentation/uikit/uitraitenvironment/…Die lange und hilfreiche Antwort von RonDiamond ist ein guter Anfang, um die Prinzipien zu verstehen. Der Code, der für mich (iOS 8+) funktioniert hat, basiert jedoch auf einer übergeordneten Methode
(UITraitCollection *)traitCollection
Fügen Sie also in InterfaceBuilder Einschränkungen mit Variationen für Breite - Kompakt hinzu, z. B. für die Eigenschaft Installiert der Einschränkung. Also Breite - Jeder gilt für Landschaft, Breite - Kompakt für Porträt.
Um Einschränkungen im Code basierend auf der aktuellen Größe des View Controllers zu ändern, fügen Sie Ihrer UIViewController-Klasse einfach Folgendes hinzu:
quelle
Wie viel anders wird Ihr Querformatmodus sein als Ihr Hochformatmodus? Wenn es sehr unterschiedlich ist, ist es möglicherweise eine gute Idee, einen anderen Ansichts-Controller zu erstellen und ihn zu laden, wenn sich das Gerät im Querformat befindet
Beispielsweise
quelle
Swift 5 Version. Es funktioniert gut.
quelle
Schneller 3.0-Code für die @ RonDiamond-Lösung
quelle