I've been dealing with a UI glitch on iPadOS 13.1.3 that is related to device orientation. Is there any solution or workaround for this?
Issue
Description
Let's have screen A that displays modally screen B. Screen A is locked to portrait only and screen B supports all orientations. If screen A is displayed, device is rotated to landscape then and screen B is about to be displayed, screen A is resized incorrectly first which results a wierd glitch.
Images
The left images is taken on iPadOS 13.1.3 that produces the UI glitch. Image on the right is recorded on iPad with iOS 12.4.1 installed where the layout is correct. All the attached images are part of the github project linked below.
Project
Please, feel free to have a closer look on the issue by using this repository.
Thanks.
Edit:
The glitch no longer occurs on iPadOS 13.2.
I worked around it like this:
Delete your implementation of func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?). Let's let the view controllers handle this.
In VC1:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.portrait
}
Also delete the "hacky solution".
In VC2:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.all
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
.portrait
}
So what we get is that VC2 appears initially in portrait but can then be rotated.
If you want VC2 to rotate immediately into landscape after appearing, then add this:
var appeared = false
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
appeared = true
UIViewController.attemptRotationToDeviceOrientation()
}
Related
I am have 3 VC and in Xcode I enabled only Portrait mode but for one VC need enable Landscape Left & Right mode.
How I can enabled these orientation programmatically?
I am try use this code but it's don't help me:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .all
}
override open var shouldAutorotate: Bool {
return true
}
Also did try use next way:
Enable all screen orientation on xcode, and set for two VC only portrait mode, it's not bad BUT my VC have few subviews and when I hold phone in landscape orientation and then start program, VC have portrait orientation but other subview which I am create PROGRAMMATICALLY change self position on screen.
How I am can solve this problem?
My entire app is portrait mode. However, one screen needs to be able to rotate to landscape (for playing video). I am able to enable all orientation rotations with no problem via #Jonathan Danek's answer.
In my AppDelegate I have:
static var orientationLock = UIInterfaceOrientationMask.portrait
and subsequently:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}
So to enable rotation for all orientations, I do the following as the video view-controller is presented:
AppDelegate.orientationLock = UIInterfaceOrientationMask.all
UINavigationController.attemptRotationToDeviceOrientation()
This works great š ..the problem is when I try to change it back to only portrait mode.
I am trying this as the video view-controller is dismissed:
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UINavigationController.attemptRotationToDeviceOrientation()
..but it does not trigger the above AppDelegate's supportedInterfaceOrientationsForWindow function if the video view-controller is currently rotated to Landscape. What's interesting is that it will trigger the function if the video view-controller is currently rotated to Portrait.
So I'm wondering how I can set my one view-controller to have all orientations, but then change it back to just portrait?
Have you tried to overwrite supportedInterfaceOrientations in your controller? That might help.
Example:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.all
}
Returns all of the interface orientations that the view controller supports.
Apple Doc - supportedInterfaceOrientations
Swift 5.1 short version:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.all
}
I am creating an application with support only for portrait mode. I don't want Landscape or Portrait upside down. I tried some code. Which allows me to lock in portrait mode.
I am using navigationcontroller and presentviewcontroller. Now my problem is:
1. If I rotate my device upside down and open my application it opens in upside down mode which is wrong.
2. I click some button and enter to presentviewcontroller it returns to portrait mode.
I want all the navigationcontroller and presentviewcontroller in portrait mode
My codes:
I set device orientarion portrait in Target -> General -> Deployment Info -> Portrait
In my appdelagate.swift:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
In my First view controller. Which is basically child of Navigation Controller
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return [UIInterfaceOrientationMask.Portrait ]
}
Edit 1:
Also I set StoryBoard -> ViewController -> Attribute Inspector -> Orientation -> Portrait
Edit 2:
My settings file
Go To Target --> General and set Orientation Mode to Portrait.
Also check info.plist. Make sure Supported Interface Orientations contains only one value(Portrait). Sometime it removes from settings but not updated in plist file.
If your app is not supporting split screen view than you should check the option to Require full screen. This fixed my issue with portrait mode.
If this does not resolve issue add Supported interface orientations Key of Array type in your info.plist. And String item to that array with value Portrait (bottom home button)
For me the only working solution was to add:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
.portrait
}
in the app's delegate class, as indicated in the question itself.
I'm using SwiftUI without any storyboard file, even for the splashscreen.
Iām making iOS application using swift. My app has many view and all view has UITabBar as root view. I need to support landscape orientation for only one tabbar item.
tabBar 1 - Portrait only
tabBar 2 - Portrait only
tabBar 3 - Portrait only
tabBar 4 - Landscape & Portrait
How can i do that?
I have a working solution based on this answer here: https://stackoverflow.com/a/24928474/1359306
So first off, make sure the supported orientations are checked in Target Settings > General > Deployment Info.
Add this code (taken from the linked answer) to your app delegate:
internal var shouldRotate = false
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if shouldRotate {
return .AllButUpsideDown
} else {
return .Portrait
}
}
Then in your landscape only view controller, put the following code in viewDidAppear (NOT viewDidLoad!) to enable both portrait and landscape view:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.shouldRotate = true
And the opposite to viewWillDisappear to disable landscape again.
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.shouldRotate = false
I am also hiding my tabs and status bar when the app is in landscape, which feels like a much better UX than tapping a tab and automatically rotating the screen.
There are a few things which in my case I don't have to worry about.
Displaying a modal view from a landscape view would cause issues
I am facing an orientation issue in iOS 8 and later in iPad. My application requires both landscape right and landscape left orientations in iPad. But it supports only landscape right orientation in iPad with iOS 8. If you try to change the orientation , the orientation of status bar is getting changed, but the application's view controller orientation remains unchanged. I am using Xcode 6.2 and swift. I have added all orientations in plist and used func shouldAutorotate() -> Bool{}
func supportedInterfaceOrientations() -> Int {} methods as per the requirement. Please give me a solution. Thanks in advance.
I wanted to have only portrait in iphone and all modes in iPad. Overriding viewcontroller shouldrotate didn't help me out. With research found that , appdelegate can handle the rotation. Please find the below code.Hope it helps you.
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {
var orientation = Int(UIInterfaceOrientationMask.Portrait.toRaw())
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
orientation = Int(UIInterfaceOrientationMask.All.toRaw())
}
return orientation
}