Kann mir bitte jemand den "richtigen" oder "besten" Ansatz für die Arbeit mit Hoch- und Querformat-Oberflächenorientierungen in iOS 8 nennen? Es scheint, dass alle Funktionen, die ich für diesen Zweck verwenden möchte, in iOS 8 veraltet sind, und meine Forschung hat keine klare, elegante Alternative ergeben. Soll ich mir wirklich die Breite und Höhe ansehen, um selbst zu bestimmen, ob wir uns im Hoch- oder Querformat befinden?
Wie sollte ich beispielsweise in meinem View-Controller den folgenden Pseudocode implementieren?
if we are rotating from portrait to landscape then
do portrait things
else if we are rotating from landscape to portrait then
do landscape things
Apple empfiehlt die Verwendung von Größenklassen als grobes Maß für den verfügbaren Bildschirmbereich, damit die Benutzeroberfläche Layout und Erscheinungsbild erheblich ändern kann. Beachten Sie, dass ein iPad im Hochformat die gleichen Größenklassen aufweist wie im Querformat (normale Breite, normale Höhe). Dies bedeutet, dass Ihre Benutzeroberfläche zwischen den beiden Ausrichtungen mehr oder weniger ähnlich sein sollte.
Der Wechsel von Hochformat zu Querformat auf einem iPad ist jedoch so bedeutend, dass Sie möglicherweise kleinere Anpassungen an der Benutzeroberfläche vornehmen müssen, obwohl sich die Größenklassen nicht geändert haben. Da die Methoden für die Schnittstellenorientierung in UIViewController
veraltet sind, empfiehlt Apple) jetzt, die folgende neue Methode in UIViewController
als Ersatz zu implementieren:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// Code here will execute before the rotation begins.
// Equivalent to placing it in the deprecated method -[willRotateToInterfaceOrientation:duration:]
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Place code here to perform animations during the rotation.
// You can pass nil or leave this block empty if not necessary.
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Code here will execute after the rotation has finished.
// Equivalent to placing it in the deprecated method -[didRotateFromInterfaceOrientation:]
}];
}
Groß! Jetzt erhalten Sie Rückrufe direkt vor und nach dem Start der Rotation. Aber wie sieht es eigentlich damit aus, zu wissen, ob es sich um eine Rotation im Hoch- oder Querformat handelt?
Apple empfiehlt, Rotation einfach als Änderung der Größe der übergeordneten Ansicht zu betrachten. Mit anderen Worten, während einer iPad-Rotation vom Hoch- zum Querformat können Sie sich das als die Ansicht auf Stammebene vorstellen, bei der lediglich das bounds.size
von {768, 1024}
bis {1024, 768}
. Wenn Sie das dann wissen, sollten Sie das size
verwenden, das in das viewWillTransitionToSize:withTransitionCoordinator:
Methode oben, um herauszufinden, ob Sie sich zum Hoch- oder Querformat drehen.
Wenn Sie einen noch nahtloseren Weg zur Migration von Legacy-Code auf die neue iOS 8-Methode suchen, sollten Sie die Verwendung von diese einfache Kategorie in UIView in Betracht ziehen, um festzustellen, ob eine Ansicht "Hochformat" ist. oder "Landschaft" basierend auf seiner Größe.
Um es zusammenzufassen:
viewWillTransitionToSize:withTransitionCoordinator:
Rückruf in UIViewController.statusBarOrientation
- im Grunde genommen eine Eigenschaft auf Geräteebene -, um zu bestimmen, ob eine Ansicht für "Hochformat" oder "Querformat" erstellt werden soll. Die Ausrichtung in der Statusleiste sollte nur von Code verwendet werden, der sich mit Dingen wie UIWindow
befasst, die sich tatsächlich im Stammverzeichnis der App befinden.Basierend auf der sehr detaillierten (und akzeptierten) Antwort von smileyborg ist hier eine Anpassung mit Swift 3:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil, completion: {
_ in
self.collectionView.collectionViewLayout.invalidateLayout()
})
}
Und in der UICollectionViewDelegateFlowLayout
Implementierung,
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// retrieve the updated bounds
let itemWidth = collectionView.bounds.width
let itemHeight = collectionView.bounds.height
// do whatever you need to do to adapt to the new size
}
Ich benutze einfach das Benachrichtigungscenter:
Füge eine Orientierungsvariable hinzu (wird am Ende erklärt)
//Above viewdidload
var orientations:UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
Benachrichtigung hinzufügen, wenn die Ansicht angezeigt wird
override func viewDidAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationChanged:", name: UIDeviceOrientationDidChangeNotification, object: nil)
}
Benachrichtigung entfernen, wenn die Ansicht ausgeblendet wird
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIDeviceOrientationDidChangeNotification, object: nil)
}
Erhält die aktuelle Ausrichtung, wenn eine Benachrichtigung ausgelöst wird
func orientationChanged (notification: NSNotification) {
adjustViewsForOrientation(UIApplication.sharedApplication().statusBarOrientation)
}
Überprüft die Ausrichtung (Hoch-/Querformat) und verarbeitet Ereignisse
func adjustViewsForOrientation(orientation: UIInterfaceOrientation) {
if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown)
{
if(orientation != orientations) {
println("Portrait")
//Do Rotation stuff here
orientations = orientation
}
}
else if (orientation == UIInterfaceOrientation.LandscapeLeft || orientation == UIInterfaceOrientation.LandscapeRight)
{
if(orientation != orientations) {
println("Landscape")
//Do Rotation stuff here
orientations = orientation
}
}
}
Der Grund, warum ich eine Ausrichtungsvariable hinzufüge, ist, dass beim Testen auf einem physischen Gerät die Ausrichtungsbenachrichtigung bei jeder kleinen Bewegung im Gerät aufgerufen wird, und nicht nur, wenn es rotiert. Das Hinzufügen der var- und if-Anweisungen ruft den Code nur dann auf, wenn er in die entgegengesetzte Richtung gewechselt ist.
Unter dem Gesichtspunkt der Benutzeroberfläche glaube ich, dass die Verwendung von Größenklassen der von Apple empfohlene Ansatz für den Umgang mit Schnittstellen in verschiedenen Ausrichtungen, Größen und Maßstäben ist.
Siehe den Abschnitt: Merkmale beschreiben die Größenklasse und den Maßstab einer Schnittstelle hier: https://developer.Apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles /iOS8.html
"iOS 8 bietet neue Funktionen, die den Umgang mit Bildschirmgröße und Ausrichtung wesentlich vielseitiger gestalten."
Dies ist auch ein guter Artikel: https://carpeaqua.com/thinking-in-terms-of-ios-8-size-classes/
[~ # ~] bearbeiten [~ # ~] Aktualisierter Link: https://carpeaqua.com/2014/06/14/ Denken in Bezug auf IOS-8-Größenklassen / (Credit: Koen)