"InterfaceOrientation" ist in iOS 8 veraltet. So ändern Sie diese Methode Ziel C.

75

Ich habe eine einfache Kameraansicht von Cocoa Controls heruntergeladen, die diese Methode verwenden

- (AVCaptureVideoOrientation)orientationForConnection
{
    AVCaptureVideoOrientation videoOrientation = AVCaptureVideoOrientationPortrait;
    switch (self.interfaceOrientation) {
        case UIInterfaceOrientationLandscapeLeft:
            videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
            break;
        case UIInterfaceOrientationLandscapeRight:
            videoOrientation = AVCaptureVideoOrientationLandscapeRight;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
            break;
        default:
            videoOrientation = AVCaptureVideoOrientationPortrait;
            break;
    }
    return videoOrientation;
}

Das Problem ist, dass "interfaceOrientation" in iOS 8 veraltet ist, aber ich weiß nicht, was und wie ich dies im Switch-Zustand ersetzen soll.

GetMe4GetMe
quelle

Antworten:

145

Das Abrufen der Geräteorientierung ist nicht korrekt. Beispielsweise befindet sich das Gerät möglicherweise im Querformat, aber ein Ansichts-Controller, der nur Hochformat unterstützt, bleibt im Hochformat.

Verwenden Sie stattdessen Folgendes:

[[UIApplication sharedApplication] statusBarOrientation]

Ein weiterer Bonus ist, dass immer noch die UIInterfaceOrientation-Enumeration verwendet wird, sodass nur sehr wenig von Ihrem Code geändert werden muss.

cetcet
quelle
9
statusBarOrientationveraltet in iOS 9 - developer.apple.com/documentation/uikit/uiapplication/…
Pang
21

Seit iOS8 empfiehlt Apple, TraitCollections (Größenklassen) anstelle von interfaceOrientation zu verwenden.

Darüber hinaus gibt es seit iOS 9 und dem neuen iPad "Multitasking" einige Fälle, in denen die Geräteorientierung nicht mit den Fensterproportionen übereinstimmt! (Unterbrechen der Benutzeroberfläche Ihrer Anwendung)

Daher sollten Sie auch bei der Verwendung von regulären Größenklassen sehr vorsichtig sein, da nicht der gesamte iPad-Bildschirm belegt werden muss.

Manchmal erfüllt TraitCollections nicht alle Ihre Designanforderungen. In diesen Fällen empfiehlt Apple, die Grenzen der Ansicht zu vergleichen:

if view.bounds.size.width > view.bounds.size.height {
    // ...
}

Ich war ziemlich überrascht, aber Sie können das WWDC 2015-Video Erste Schritte mit Multitasking auf dem iPad in iOS 9 um 21'15 Uhr lesen.

Vielleicht suchen Sie wirklich nach der Geräteorientierung und nicht nach den Bildschirm- oder Fensterproportionen. Wenn Sie sich für die Gerätekamera interessieren, sollten Sie weder TraitCollection noch Ansichtsgrenzen verwenden.

vmeyer
quelle
In der Tat ist es erwähnt. Vielen Dank!!
Ankish Jain
Gibt es eine empfohlene Methode, um festzustellen, ob sich das Gerät links oder rechts im Querformat befindet? Es ist wirklich wichtig mit der Kerbe des iPhone X :(
Pavel Alexeev
Nun, Sie können es verwenden, [[UIDevice currentDevice] orientation]wenn Sie die tatsächliche Geräteorientierung überprüfen möchten, aber Sie sollten es nicht für die iPhone X-Anpassung verwenden. Bitte verwenden Sie einen neuen sicheren Bereich für iOS 11 oder einen alten Layoutrand.
Vmeyer
3

Swift 4+ Version

UIApplication.shared.statusBarOrientation
Abhishek Jain
quelle
1
In iOS 13 gibt diese Methode an, dass "'statusBarOrientation' veraltet ist: zuerst in iOS 13.0 veraltet - Verwenden Sie stattdessen die Eigenschaft interfaceOrientation der Fensterszene." Nachricht
Peter Johnson
2

Die Verwendung der -orientationEigenschaft von UIDevice ist nicht korrekt (auch wenn sie in den meisten Fällen funktionieren könnte) und kann zu einigen Fehlern führen. UIDeviceOrientationBerücksichtigen Sie beispielsweise auch die Ausrichtung des Geräts, wenn es nach oben oder unten zeigt. Für diese gibt es kein UIInterfaceOrientationEnum- Paar Werte.
Wenn Sie Ihre App in einer bestimmten Ausrichtung sperren, gibt Ihnen UIDevice außerdem die Geräteorientierung, ohne dies zu berücksichtigen.
Auf der anderen Seite hat iOS8 die interfaceOrientationEigenschaft für die UIViewControllerKlasse veraltet .
Es stehen 2 Optionen zur Verfügung, um die Ausrichtung der Benutzeroberfläche zu ermitteln:

  • Verwenden Sie die Ausrichtung der Statusleiste
  • Verwenden Sie Größenklassen. Wenn diese auf dem iPhone nicht überschrieben werden, können Sie die aktuelle Ausrichtung der Benutzeroberfläche besser verstehen

Was noch fehlt, ist eine Möglichkeit, die Richtung einer Änderung der Schnittstellenorientierung zu verstehen, die bei Animationen sehr wichtig ist.
In der Sitzung der WWDC 2014 "View Controller Advancement in iOS8" bietet der Sprecher auch eine Lösung für dieses Problem mit der Methode, die ersetzt -will/DidRotateToInterfaceOrientation.

Hier wurde die vorgeschlagene Lösung teilweise umgesetzt:

-(void) viewWillTransitionToSize:(CGSize)s withTransitionCoordinator:(UIVCTC)t {
    orientation = [self orientationFromTransform: [t targetTransform]]; 
    oldOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 
    [self myWillRotateToInterfaceOrientation:orientation duration: duration]; 
    [t animateAlongsideTransition:^(id <UIVCTCContext>) {
         [self myWillAnimateRotationToInterfaceOrientation:orientation
                                                  duration:duration];
      }
      completion: ^(id <UIVCTCContext>) {
         [self myDidAnimateFromInterfaceOrientation:oldOrientation];
      }];
}
Andrea
quelle
Wie leitet die Methode OrientationFromTransform: die Orientierung von der Transformation ab?
Chandra
0

Bei Verwendung UIApplication.shared.statusBarOrientationzeigt Xcode 11 die Warnung an'statusBarOrientation' was deprecated in iOS 13.0: Use the interfaceOrientation property of the window scene instead.

Diese Antwort ist in Swift 5 enthalten und unterstützt sowohl iOS 13 als auch niedrigere Versionen. Es wird Folgendes angenommen:

  • Sie erstellen nur eine Szene und niemals mehr als eine
  • Sie möchten Ihren Code in einer bestimmten Ansicht enthalten
  • Sie haben eine Ansicht mit einer Mitgliedsvariablen previewLayervom TypAVCaptureVideoPreviewLayer

Fügen Sie zunächst in Ihrem SceneDelegate.swiftFeld die folgenden Zeilen hinzu:

    static var lastCreatedScene: UIWindowScene?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let newScene = (scene as? UIWindowScene) else { return }
        Self.lastCreatedScene = newScene
    }

Fügen Sie dann aus Ihrer Sicht die folgende Funktion hinzu und rufen Sie sie auf layoutSubviews():

    func refreshOrientation() {
        let videoOrientation: AVCaptureVideoOrientation
        let statusBarOrientation: UIInterfaceOrientation
        if #available(iOS 13, *) {
            statusBarOrientation = SceneDelegate.lastCreatedScene?.interfaceOrientation ?? .portrait
        } else {
            statusBarOrientation = UIApplication.shared.statusBarOrientation
        }
        switch statusBarOrientation {
        case .unknown:
            videoOrientation = .portrait
        case .portrait:
            videoOrientation = .portrait
        case .portraitUpsideDown:
            videoOrientation = .portraitUpsideDown
        case .landscapeLeft:
            videoOrientation = .landscapeLeft
        case .landscapeRight:
            videoOrientation = .landscapeRight
        @unknown default:
            videoOrientation = .portrait
        }
        self.previewLayer.connection?.videoOrientation = videoOrientation
    }
Bart van Kuik
quelle