Getting device orientation in Swift

2019-01-10 16:56发布

问题:

I was wondering how I can get the current device orientation in Swift? I know there are examples for Objective-C, however I haven't been able to get it working in Swift.

I am trying to get the device orientation and put that into an if statement.

This is the line that I am having the most issues with:

[[UIApplication sharedApplication] statusBarOrientation]

回答1:

you can use:

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)")        
}

or

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

with Notification you can check: IOS8 Swift: How to detect orientation change?

NOTE : didRotateFromInterfaceOrientation is Deprecated Use viewWillTransitionToSize for iOS 2.0 and later



回答2:

To get the status bar (and therefor UI) orientation like the Objective-C code you have, it's simply:

UIApplication.sharedApplication().statusBarOrientation

You can also use the orientation property of UIDevice:

UIDevice.currentDevice().orientation

However, that may not match what orientation your UI is in. From the docs:

The value of the property is a constant that indicates the current orientation of the device. This value represents the physical orientation of the device and may be different from the current orientation of your application’s user interface. See “UIDeviceOrientation” for descriptions of the possible values.



回答3:

Apple recently got rid of the idea of Landscape vs. Portrait and prefers we use screen size. However, this works:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.currentDevice().orientation.isLandscape.boolValue {
        print("landscape")
    } else {
        print("portrait")
    }
}


回答4:

To find current device orientation simply use this code:

UIApplication.sharedApplication().statusBarOrientation

for swift 3.0

UIApplication.shared.statusBarOrientation



回答5:

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 answer: this is how I do it,

1.works for all kinds of view controller

2.also work when the user rotates the app

3.also for the first time install the app



回答6:

Swift 4:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if UIDevice.current.orientation.isLandscape {
            print("landscape")
        } else {
            print("portrait")
        }
    }


回答7:

I had issues with using InterfaceOrientation, it worked OK except it wasn't accessing the orientation on loading. So I tried this and it's a keeper. This works because the bounds.width is always in reference to the current orientation as opposed to nativeBounds.width which is absolute.

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

I call this from willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) and from viewDidLoad but it flexible.

Thanks to zSprawl for the pointer in that direction. I should point out that this is only good for iOS 8 and later.



回答8:

So, if Apple is deprecating the whole orientation string thing ("portrait","landscape"), then all you care about is the ratio of width to height. (kinda like @bpedit's answer)

When you divide the width by the height, if the result is less than 1, then the mainScreen or container or whatever is in "portrait" "mode". If the result is greater than 1, it's a "landscape" painting. ;)

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")
    }
}

(I'm guessing that if you use this approach then you probably don't really care about specifically handling the condition when the ratio is exactly 1, equal width and height.)



回答9:

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


回答10:

Swift 3, based on Rob's answer

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if (size.width / size.height > 1) {
        print("landscape")
    } else {
        print("portrait")
    }
}


回答11:

Swift 3+

Basically:

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")
    }
}

:)



回答12:

I found that the alternative code in Swift for the Obj-C code

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

is

if UIApplication.shared.statusBarOrientation.isLandscape

Note: we are trying to find the status bar orientation is landscape or not. If it is landscape then the if statement is true.