webentwicklung-frage-antwort-db.com.de

Wie gehe ich mit Orientierungsänderungen in iOS 8 "richtig" um?

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
99
rmp251

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:

  1. Sie sollten Größenklassen verwenden, um zu bestimmen, wann grundsätzlich unterschiedliche Benutzeroberflächen angezeigt werden sollen (z. B. eine "iPhone-ähnliche" Benutzeroberfläche im Vergleich zu einer "iPad-ähnlichen" Benutzeroberfläche).
  2. Wenn Sie kleinere Anpassungen an Ihrer Benutzeroberfläche vornehmen müssen, wenn sich die Größenklassen nicht ändern , aber die Größe Ihres Containers (übergeordnete Ansicht), z. B. bei einem iPad dreht, benutze den viewWillTransitionToSize:withTransitionCoordinator: Rückruf in UIViewController.
  3. Jede Ansicht in Ihrer App sollte nur Layoutentscheidungen treffen, die auf dem Raum basieren, in dem das Layout erstellt wurde. Lassen Sie die natürliche Hierarchie der Ansichten diese Informationen nach unten kaskadieren.
  4. Verwenden Sie auch nicht die Eigenschaft 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.
253
smileyborg

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
}
16
CMont

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.

11
inVINCEable

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)

2
Aaron