In Swift, how to get the device orientation correctly right after it's launched?
I have tested many times about orientation, so I have summed up some experience.
In all iPhone devices, except iPhone6(s) plus, the only interface orientation is .portrait
. If App is launched in landscape mode, there must be a change of orientation. One will receive the UIDeviceOrientationDidChangeNotification
. It's an appropriate time to get the orientation.
Regarding the launching when in landscape with iPhone6, the orientation after the launch will change once:
The launching when in landscape with iPhone6 plus, after launch the orientation never changed:
Two different screenshot with the same app,
So before the app does change orientation, the orientation is still like in the home page.
In viewDidLoad
, the orientation has not changed yet, the log will be the wrong direction.
Swift - How to detect orientation changes
let const = "Background" //image name
let const2 = "GreyBackground" // image name
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = UIImage(named: const)
// Do any additional setup after loading the view.
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("Landscape")
imageView.image = UIImage(named: const2)
} else {
print("Portrait")
imageView.image = UIImage(named: const)
}
}
How to detect orientation change?
Here's how I got it working:
In AppDelegate.swift
inside the didFinishLaunchingWithOptions
function I put:
NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
and then inside the AppDelegate class I put the following function:
func rotated() {
if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
print("Landscape")
}
if UIDeviceOrientationIsPortrait(UIDevice.current.orientation) {
print("Portrait")
}
}
Setting device orientation in Swift iOS
You can paste these methods in the ViewController of each view that needs to be portrait:
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
How to check if device orientation is landscape left or right in swift?
you can do something like,
if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft{
}
else if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight{
}
else if UIDevice.currentDevice().orientation == UIDeviceOrientation.UIDeviceOrientationPortraitUpsideDown{
}
else if UIDevice.currentDevice().orientation == UIDeviceOrientation.UIDeviceOrientationPortrait{
}
SWIFT 5
if UIDevice.current.orientation.isLandscape {
} else if UIDevice.current.orientation.isFlat {
} else if UIDevice.current.orientation.isPortrait {
} else if UIDevice.current.orientation.isValidInterfaceOrientation {
}
SWIFT 3
if UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft {
} else if UIDevice.current.orientation == UIDeviceOrientation.landscapeRight {
} else if UIDevice.current.orientation == UIDeviceOrientation.portrait {
} else if UIDevice.current.orientation == UIDeviceOrientation.portraitUpsideDown {
}
iOS: Device orientation on load
EDIT: I mis-read your question. This will allow you to start your application in certain orientations. Just realized you're trying to figure out the orientation on launch.
There is a method to check the status bar orientation on UIApplication
:
[[UIApplication sharedApplication] statusBarOrientation];
Original answer
Try setting the application's accepted device orientations in the plist file:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
This will indicate that your application supports Portrait (home button at the bottom), landscape left, and landscape right.
Then, in your UIViewControllers, you will need to override the shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
method to return YES when the app should rotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}
This will tell the UIViewController to auto rotate if the device is in one of your supported orientations. If you wanted to support the upside-down orientation as well (portrait with home button on top) then add that to your plist and just return YES out of this method.
Let us know how it works out.
UIDevice orientation returns portrait when device launches as landscape
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
How to change Device Orientation programmatically in Swift?
For each VC declare this variable w/ desired orientation. This is for portrait.
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait }
Then on appearance enforce the desired orientation.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.setAnimationsEnabled(false)
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true)
}
Related Topics
iOS Facebook Login "Given Url Is Not Allowed by the Application Configuration"
Keep Getting "Unbalanced Calls to Begin/End Appearance Transitions for <Viewcontroller>" Error
Parse Starter Project Login and Register View Controllers Errors
How to Remove the Bottom Gap of Uipageviewcontroller
Secure Contents in Documents Directory
Youtube Video Autoplay Inside Uiwebview
Extract Last Word in String with Swift
Disable Warning Dialog If Bluetooth Is Powered Off iOS
iOS 7.0 and Arc: Uitableview Never Deallocated After Rows Animation
iOS 11 - Unable to Change Navigation Bar Height
Swift Framework Does Not Include Symbols from Extensions to Generic Structs
iOS 11 Animated Gif Display in Uiimageview
Multiple Uitableview in Single Viewcontroller
iOS - Using Storyboard and Autolayout to Center the Uiscrollview