Heres a sample code that will print if the device is "portrait" or "landscape" when it first launches and also when it detects an orientation change.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getOrientation()
}
func getOrientation() {
let orientation = UIDevice.current.orientation
if orientation == .landscapeLeft || orientation == .landscapeRight {
print("landscape")
}
else {
print("portrait")
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
getOrientation()
}
}
If I launch the app with the phone portrait, it works fine. However, if I launch the app with the phone in landscape, it'll detect portrait at first. But if you rotate the device afterward it'll be correct. Is this a bug or am I using UIDevice.current.orientation
incorrectly?
See, your code is perfect, but the calling is not proper. viewDidLoad
method doesn't guarantees the interface orientation or any UI related properties things it just says that view
is loaded but in case if you want to guarantee to get the proper details then you should call it under DispatchQueue.main.async(execute: block)
(Main queue) which will give proper orientation
or the other way is to call under viewDidLayoutSubviews
but this has an disadvantage of calling multiple times depending on your views and subviews are resized.
DispatchQueue.main.async {
self.getOrientation()
}
Reference: view.frame.width IS correct in viewDidLoad with storyboard, why?
Apple Docs: https://developer.apple.com/documentation/uikit/uiviewcontroller