Geräteorientierung in Swift abrufen

78

Ich habe mich gefragt, wie ich die aktuelle Geräteorientierung in Swift erhalten kann. Ich weiß, dass es Beispiele für Objective-C gibt, aber ich konnte es in Swift nicht zum Laufen bringen.

Ich versuche, die Geräteorientierung zu ermitteln und diese in eine if-Anweisung einzufügen.

Dies ist die Zeile, mit der ich die meisten Probleme habe:

[[UIApplication sharedApplication] statusBarOrientation]
user3746428
quelle
Was ist dein Problem? Das in Swift übersetzen oder die Werte bekommen, die Sie erwarten?
David Rönnqvist
1
Die Geräteorientierung stimmt nicht unbedingt mit Ihrer Benutzeroberflächenausrichtung überein. Gehäusepunkt - Legen Sie Ihr Gerät flach und testen Sie Ihren Code!
Patrick

Antworten:

70

Sie können verwenden:

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
    var text=""
    switch UIDevice.currentDevice().orientation{
    case .Portrait:
        text="Portrait"
    case .PortraitUpsideDown:
        text="PortraitUpsideDown"
    case .LandscapeLeft:
        text="LandscapeLeft"
    case .LandscapeRight:
        text="LandscapeRight"
    default:
        text="Another"
    }
    NSLog("You have moved: \(text)")        
}

SWIFT 3 UPDATE

override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
    var text=""
    switch UIDevice.current.orientation{
    case .portrait:
        text="Portrait"
    case .portraitUpsideDown:
        text="PortraitUpsideDown"
    case .landscapeLeft:
        text="LandscapeLeft"
    case .landscapeRight:
        text="LandscapeRight"
    default:
        text="Another"
    }
    NSLog("You have moved: \(text)")        
}

oder

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
}

Mit Benachrichtigung können Sie überprüfen: IOS8 Swift: Wie erkennt man Orientierungsänderungen?

HINWEIS : didRotateFromInterfaceOrientation ist veraltet. Verwenden Sie viewWillTransitionToSize für iOS 2.0 und höher

Im Falle von Face Up und Face Down funktioniert dies nicht. Wir müssen also Folgendes verwenden.

if UIApplication.shared.statusBarOrientation.isLandscape {
     // activate landscape changes
} else {
     // activate portrait changes
}
Miguel
quelle
Vielen Dank für Ihr Teilen!
ssowri1
Hmm ... was ist, wenn der Benutzer nach dem Drehen zu dieser Ansicht navigiert, würden wir die
Startausrichtung
Falls Sie diese Funktion trotz veralteter Funktion weiterhin verwenden. Vergessen Sie nicht, es in Ihrer Implementierung als Super-Methode zu bezeichnen. dh : super.didRotate(from: fromInterfaceOrientation). Aus der Apple-Dokumentation: "Ihre Implementierung dieser Methode muss irgendwann während ihrer Ausführung super aufrufen."
Bocaxica
55

Um die Ausrichtung der Statusleiste (und damit der Benutzeroberfläche) wie den von Ihnen verwendeten Objective-C-Code zu erhalten, ist es einfach:

UIApplication.sharedApplication().statusBarOrientation

Sie können auch die orientationEigenschaft von UIDevice verwenden:

UIDevice.currentDevice().orientation

Dies stimmt jedoch möglicherweise nicht mit der Ausrichtung Ihrer Benutzeroberfläche überein. Aus den Dokumenten:

Der Wert der Eigenschaft ist eine Konstante, die die aktuelle Ausrichtung des Geräts angibt. Dieser Wert stellt die physische Ausrichtung des Geräts dar und kann von der aktuellen Ausrichtung der Benutzeroberfläche Ihrer Anwendung abweichen. Beschreibungen der möglichen Werte finden Sie unter „UIDeviceOrientation“.

Mike S.
quelle
UIApplication.sharedApplication (). StatusBarOrientation ist nur auf Hauptthread
Yair hatte
Danke für deine Hilfe!
ssowri1
1
Ich habe uidevice.current.orientation.isportrait verwendet, um die Geräteorientierung zu überprüfen und die Benutzeroberfläche der App zu ändern, aber es hat sich geändert, selbst wenn das Gerät auf den Schreibtisch gestellt wurde. Aber dank Ihnen funktioniert es jetzt einwandfrei
Gulfam Khan
aktualisiert auf swift 5.1 -> UIDevice.current.orientation
Ronaldo Albertini
UIDevice.current.orientation.isPortrait funktioniert nicht, wenn die Geräteorientierung offen oder verdeckt ist. Das Überprüfen der Statusleiste wie in dieser Antwort war konsistent und hat für mich funktioniert.
Austin
26

Apple hat kürzlich die Idee von Landscape vs. Portrait losgeworden und bevorzugt die Verwendung der Bildschirmgröße. Dies funktioniert jedoch:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.currentDevice().orientation.isLandscape.boolValue {
        print("landscape")
    } else {
        print("portrait")
    }
}
zSprawl
quelle
7
Ich würde mit Ihrer Lösung feststellen, dass Apple sagt: "Wenn Sie diese Methode in Ihren benutzerdefinierten Ansichts-Controllern überschreiben, rufen Sie immer irgendwann in Ihrer Implementierung super auf"
Popmedic
25
struct DeviceInfo {
struct Orientation {
    // indicate current device is in the LandScape orientation
    static var isLandscape: Bool {
        get {
            return UIDevice.current.orientation.isValidInterfaceOrientation
                ? UIDevice.current.orientation.isLandscape
                : UIApplication.shared.statusBarOrientation.isLandscape
        }
    }
    // indicate current device is in the Portrait orientation
    static var isPortrait: Bool {
        get {
            return UIDevice.current.orientation.isValidInterfaceOrientation
                ? UIDevice.current.orientation.isPortrait
                : UIApplication.shared.statusBarOrientation.isPortrait
        }
    }
}}

swift4 Antwort: So mache ich das,

1. funktioniert für alle Arten von View Controllern

2. funktioniert auch, wenn der Benutzer die App dreht

3. Installieren Sie auch zum ersten Mal die App

Ernie Sender
quelle
1
perfekte Antwort! Danke
Torap
Schön, aber warum schreibst du es zwei Mal anstatt der @objc-Klasse? Var isLandscape: Bool {return! IsPortrait} Ich bekomme nichts Entscheidendes? ;)
Renetik
Wow, es funktioniert perfekt, da ich es nicht tun werde. Vielen Dank :)
Yogesh Patel
Woher weiß ich, dass sich die Ausrichtung geändert hat?
Daniel Springer
14

Swift 4:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if UIDevice.current.orientation.isLandscape {
            print("landscape")
        } else {
            print("portrait")
        }
    }
FBC
quelle
Was ist mit der isFlat-Orientierung?
Michał Ziobro
2
Vergessen Sie nicht, super.viewWillTransition (auf: Größe, mit: Koordinator) irgendwann in Ihrer überschreibenden Funktion aufzurufen.
Bocaxica
13

Verwenden Sie einfach diesen Code, um die aktuelle Geräteorientierung zu ermitteln:

UIApplication.sharedApplication (). StatusBarOrientation

für schnelle 3.0

UIApplication.shared.statusBarOrientation

Usman Nisar
quelle
iPad Air 1 & 2 gibt einen falschen Wert zurück, iPad 2 und iPhone sind korrekt. Ich versuche wirklich, eine zu finden, die auf allen Geräten funktioniert, aber Apple hat hier ein echtes Chaos angerichtet! :(
Steven B.
im Gegensatz zu UIDevice.current.orientation, UIApplication.shared.statusBarOrientationauf Anfangslast vorhanden ist, nicht nur , nachdem der Bildschirm gedreht wird.
Ewizard
10

Ich hatte Probleme mit der Verwendung InterfaceOrientation, es funktionierte einwandfrei, außer dass beim Laden nicht auf die Ausrichtung zugegriffen wurde. Also habe ich es versucht und es ist ein Wächter. Dies funktioniert, weil sich das bounds.widthimmer auf die aktuelle Ausrichtung bezieht und nicht nativeBounds.widthabsolut ist.

    if UIScreen.mainScreen().bounds.height > UIScreen.mainScreen().bounds.width {
        // do your portrait stuff
    } else {    // in landscape
        // do your landscape stuff
    }

Ich nenne das von willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)und nach, viewDidLoadaber es ist flexibel.

Vielen Dank an zSprawl für den Zeiger in diese Richtung. Ich sollte darauf hinweisen, dass dies nur für iOS 8 und höher gut ist.

bpedit
quelle
funktioniert NICHT auf iOS 9 & 10 iPads, nur der Anfangswert ist korrekt, alle folgenden Werte sind entgegengesetzt ausgerichtet.
Steven B.
@ Steven.B Hmmm ... funktioniert gut auf meinem iPad Air, iPad 3 und Simulator unter iOS 9. Funktionierte auch mit Betatestern. Vielleicht verwenden Sie auch anderen Code, der dies beeinflusst.
bpedit
Dieser Code funktioniert wahrscheinlich nur, wenn er in einem UIViewcontroller verwendet wird. Ich versuche, die Ausrichtung und Grenzen in einer benutzerdefinierten UIView-Klasse abzurufen, aber fast jedes Gerät, das ich teste, gibt andere Werte zurück, wenn die Ausrichtung korrekt ist, als der Rahmen oder die Grenzen immer noch falsch sind.
Steven B.
10

Wenn Apple also die gesamte Orientierungszeichenfolge ("Hochformat", "Querformat") ablehnt, ist das Verhältnis von Breite zu Höhe alles, was Sie interessiert. (irgendwie wie die Antwort von @ bpedit)

Wenn Sie die Breite durch die Höhe teilen und das Ergebnis kleiner als 1 ist, befindet sich der Hauptbildschirm oder Container oder was auch immer im "Hochformat" -Modus. Wenn das Ergebnis größer als 1 ist, handelt es sich um ein "Landschaftsbild". ;)

override func viewWillAppear(animated: Bool) {
    let size: CGSize = UIScreen.mainScreen().bounds.size
    if size.width / size.height > 1 {
        print("landscape")
    } else {
        print("portrait")
    }
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    if size.width / size.height > 1 {
        print("landscape")
    } else {
        print("portrait")
    }
}

(Ich vermute, wenn Sie diesen Ansatz verwenden, ist es Ihnen wahrscheinlich nicht wirklich wichtig, die Bedingung speziell zu behandeln, wenn das Verhältnis genau 1 ist, gleiche Breite und Höhe.)

rauben
quelle
1
Nett! Kleine Verbesserung Ihrer Antwort: Vergessen Sie nicht anzurufen super.viewWillAppear(animated)und super.viewWillTransition(to: size, with: coordinator)irgendwann in Ihren übergeordneten Funktionen
Bocaxica
8

Swift 3+

Grundsätzlich:

NotificationCenter.default.addObserver(self, selector: #selector(self.didOrientationChange(_:)), name: .UIDeviceOrientationDidChange, object: nil)

@objc func didOrientationChange(_ notification: Notification) {
    //const_pickerBottom.constant = 394
    print("other")
    switch UIDevice.current.orientation {
        case .landscapeLeft, .landscapeRight:
            print("landscape")
        case .portrait, .portraitUpsideDown:
            print("portrait")
        default:
            print("other")
    }
}

:) :)

stakovereser
quelle
Ich liebe diese Antwort. Es ist sehr nützlich für größere Bildschirme wie iPad , wo Sie nicht verwenden können , func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)als traitcollection wird immer width.regularund height.regulardamit die traitCollection nicht auf Rotation ändern. In Swift 4 wurde die Benachrichtigung in umbenannt UIDevice.orientationDidChangeNotification.
Bocaxica
3

Swift 3 , basierend auf Robs Antwort

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if (size.width / size.height > 1) {
        print("landscape")
    } else {
        print("portrait")
    }
}
Johan Tingbacke
quelle
2
Vergessen Sie nicht, super.viewWillTransition(to: size, with: coordinator)irgendwann in Ihrer übergeordneten Funktion
anzurufen
3

Ich fand, dass der alternative Code in Swift für den Obj-C-Code

if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) 

ist

if UIApplication.shared.statusBarOrientation.isLandscape

Hinweis: Wir versuchen herauszufinden, ob die Ausrichtung der Statusleiste Querformat ist oder nicht. Wenn es sich um eine Landschaft handelt, ist die if-Anweisung wahr.

Akarsh SEGGEMU
quelle
2
   override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    if (toInterfaceOrientation.isLandscape) {
        NSLog("Landscape");
    }
    else {
        NSLog("Portrait");
    }
}
Sanju
quelle
2

statusBarOrientation ist veraltet , so nicht mehr zur Verfügung zu verwenden wie in oben genannten Antworten

In diesem Code kann Orientierung erhalten, ohne sich um Abschreibungen sorgen zu müssen. Swift 5 ioS 13.2 100% getestet

struct Orientation {
    // indicate current device is in the LandScape orientation
    static var isLandscape: Bool {
        get {
            return UIDevice.current.orientation.isValidInterfaceOrientation
                ? UIDevice.current.orientation.isLandscape
                : (UIApplication.shared.windows.first?.windowScene?.interfaceOrientation.isLandscape)!
        }
    }
    // indicate current device is in the Portrait orientation
    static var isPortrait: Bool {
        get {
            return UIDevice.current.orientation.isValidInterfaceOrientation
                ? UIDevice.current.orientation.isPortrait
                : (UIApplication.shared.windows.first?.windowScene?.interfaceOrientation.isPortrait)!
        }
    }
}
Malith Kuruwita
quelle