I'm trying to develop an app on Swift that supports both portrait and landscape orientations but I don't want that the user gets the possibility to launch it in landscape mode.
So is there a way to prevent this opening in landscape while keeping the app's device orientation parameters on portrait, landscape left and landscape right, or is there a way to change the device orientation parameters from portrait only after the launch of the app with the UIInterfaceOrientationMask ?
Thanks a lot for your help!
Restrict it in AppDelegate's method -
var supportedOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return supportedOrientation
}
Override following in all view controllers -
override func viewDidAppear(_ animated: Bool) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
var orientation: UIInterfaceOrientationMask = .all
delegate.supportedOrientation = orientation
}
}
Try it and let me know if it works.
Related
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 trying to make only ONE view in my application on landscape mode when the device changes its position, -not from the beginning. And that the rest of the views work in portrait.
AppDelegate
internal var shouldRotate = false
func application(_ application: UIApplication,
supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return shouldRotate ? .allButUpsideDown : .portrait
}
viewDidLoad
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.shouldRotate = true
This works but it applies to all my pages and I only want one in particular
In the view controller that you want to be landscape-only, override supportedInterfaceOrientations and provide an OptionSet of landscape:
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return [.landscapeLeft, .landscapeRight]
}
First of all, my project hierarchy:
tab bar controller -> navigation master -> view controllers
I have one page I want to rotate in landscape mode.
My project is compatible with all the device orientation modes.
I've manually frozen all the view controllers with autorotation returning false:
override func shouldAutorotate() -> Bool {
return false
}
except the one I want to rotate. S
I'm trying this in the view controller I want to be displayed in landscape:
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
But does nothing.
Also, I experimented an issue with this method. When the app was starting in landscape, the view was displaying in landscape and was unable to rotate. I manage to fix it with this method In my app delegate:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if(self.restrictRotation == false){
return UIInterfaceOrientationMask.Portrait//UIInterfaceOrientationMaskPortrait
}
else{
return UIInterfaceOrientationMask.All//UIInterfaceOrientationMaskAll
}
}
And in viewDidLoad setting the var to true where I want to allow rotations:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.restrictRotation = true
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
I've tested with the debugger and the method application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) is called, but the app don't rotate. I guess is because with a tab bar and a navigation controller, things has to be done differently, but don't know how exactly. Can anyone help with this?
I have a universal app with a UISplitViewController. I want the iPad version to work in both portrait and landscape but I only want the app to work in portrait on iPhone. I tried using the following on my Main View Controller and it did not work:
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
I think the problem is that the split view controller overrides the these two methods. Any ideas?
i think this is what you looking for
[splitViewController setHidesMasterViewInPortrait:NO];
I managed to figure it out by setting the supported app interface orientations at launch in the AppDelegate:
let deviceIdiom = UIScreen.mainScreen().traitCollection.userInterfaceIdiom
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if deviceIdiom == .Pad {
return UIInterfaceOrientationMask.All
}
return UIInterfaceOrientationMask.Portrait
}
I have 10 view controllers in my app and i want only one view controller to be viewed in portrait and landscape mode and the rest should only be viewed in portrait mode.
Note: I am using UINavigationController.
Any help is appreciated!
I had the same problem, but found a solution:
First, allow Landscape mode for your App in the basic settings. Then modify your AppDelegate:
internal var shouldRotate = false
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return shouldRotate ? .allButUpsideDown : .portrait
}
For every Controller, where landscape mode should be allowed, add the following code to the viewDidLoad() :
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.shouldRotate = true
That allows for the entire application to be shown in landscape mode. But it should be only in this controller, so add following code in viewWillDissappear() to set the shouldRotate var in the AppDelegate to false:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.shouldRotate = false
}