Before iOS 8, we used below code in conjunction with supportedInterfaceOrientations and shouldAutoRotate delegate methods to force app orientation to any particular orientation. I used below code snippet to programmatically rotate the app to desired orientation. Firstly, I am changing the status bar orientation. And then just presenting and immediately dismissing a modal view rotates the view to desired orientation.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
But this is failing in iOS 8. Also, I have seen some answers in stack overflow where people suggested that we should always avoid this approach from iOS 8 onwards.
To be more specific, my application is a universal type of application. There are three controllers in total.
First View controller- It should support all orientations in iPad and only portrait (home button down) in iPhone.
Second View controller- It should support only landscape right in all conditions
Third View controller- It should support only landscape right in all conditions
We are using navigation controller for page navigation. From the first view controller, on a button click action, we are pushing the second one on stack. So, when the second view controller arrives, irrespective of device orientation, the app should lock in landscape right only.
Below is my shouldAutorotate
and supportedInterfaceOrientations
methods in second and third view controller.
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotate {
return NO;
}
Is there any solution for this or any better way of locking a view controller in particular orientation for iOS 8. Please help!!
For me, the top level VC needed to implement the orientation overrides. Using VC's down the stack will have no effect if the top VC is not implementing.
Only VC-Main is listened to, essentially in my testing.
For iOS 7 - 10:
Objective-C:
Swift 3:
Just call it in
- viewDidAppear:
of the presented view controller.I tried a few solutions in here and the important thing to understand is that it's the root view controller that will determine if it will rotate or not.
I created the following objective-c project github.com/GabLeRoux/RotationLockInTabbedViewChild with a working example of a
TabbedViewController
where one child view is allowed rotating and the other child view is locked in portrait.It's not perfect but it works and the same idea should work for other kind of root views such as
NavigationViewController
. :)My solution
In
AppDelegate
:XXViewController
is the ViewController you want to support Landscape mode.Then Sunny Shah's solution would work in your
XXViewController
on any iOS version:This is the utility function to find the top most ViewController.
If you are using navigationViewController you should create your own superclass for this and override:
this will disable rotation in SecondViewController but if you push your SecondViewController when your device is on portrait orientation then your SecondViewController will appear in portrait mode.
Assume that you are using storyboard. You have to create manual segue (How to) and in your "onClick" method:
This will force landscape orientation before your superclass disable autorotate feature.
Orientation rotation is a little more complicated if you are inside a
UINavigationController
orUITabBarController
. The problem is that if a view controller is embedded in one of these controllers the navigation or tab bar controller takes precedence and makes the decisions on autorotation and supported orientations.I use the following 2 extensions on UINavigationController and UITabBarController so that view controllers that are embedded in one of these controllers get to make the decisions.
Give View Controllers the Power!
Swift 2.3
Swift 3
Now you can override the
supportedInterfaceOrientations
method or you can overrideshouldAutoRotate
in the view controller you want to lock down otherwise you can leave out the overrides in other view controllers that you want to inherit the default orientation behavior specified in your app's plistDisable Rotation
Lock to Specific Orientation
In theory this should work for all complex view controller hierarchies, but I have noticed an issue with UITabBarController. For some reason it wants to use a default orientation value. See the following blog post if you are interested in learning about how to work around some of the issues:
Lock Screen Rotation