iOS 6: How do I restrict some views to portrait and allow others to rotate?
I had the same problem and found a solution that works for me.To make it work, it is not sufficient to implement - (NSUInteger)supportedInterfaceOrientations
in your UINavigationController.You also need to implement this method in your controller #3, which is the first one to be portrait-only after popping controller #4.So, I have the following code in my UINavigationController:
- (BOOL)shouldAutorotate{ return YES;}- (NSUInteger)supportedInterfaceOrientations{ if (self.isLandscapeOK) { // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown return UIInterfaceOrientationMaskAll; } return UIInterfaceOrientationMaskPortrait;}
In view controller #3, add the following:
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait;}
You don't need to add anything to your view controllers #1, #2, and #4.This works for me, I hope it will help you.
Add a CustomNavigationController
Override these methods in it:
-(BOOL)shouldAutorotate{ return [[self.viewControllers lastObject] shouldAutorotate];}-(NSUInteger)supportedInterfaceOrientations{ return [[self.viewControllers lastObject] supportedInterfaceOrientations];}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];}
Now add all orientations in the plist
In the view controller add only the required ones:
-(BOOL)shouldAutorotate{ return YES;}-(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait;}
these methods override the navigation controller methods
After looking through every answer in countless similar questions on SO, none of the answers worked for me, but they did give me some ideas. Here's how I ended up solving the problem:
First, make sure your Supported Interface Orientations in your project's target contain all orientations that you want for your rotating view.
Next, make a category of UINavigationController
(since Apple says not to subclass it):
@implementation UINavigationController (iOS6AutorotationFix)-(BOOL)shouldAutorotate { return [self.topViewController shouldAutorotate];}@end
Import that category and the view controller that you want to be able to rotate (which I'll call RotatingViewController
) to your highest level view controller, which should contain your navigation controller. In that view controller, implement shouldAutorotate
as follows. Note that this should not be the same view controller that you want to rotate.
-(BOOL)shouldAutorotate { BOOL shouldRotate = NO; if ([navigationController.topViewController isMemberOfClass:[RotatingViewController class]] ) { shouldRotate = [navigationController.topViewController shouldAutorotate]; } return shouldRotate;}
Finally, in your RotatingViewController
, implement shouldAutorotate
and supportedInterfaceOrientations
as follows:
-(BOOL)shouldAutorotate { // Preparations to rotate view go here return YES;}-(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; // or however you want to rotate}
The reason you need to do this is because iOS 6 gives control of rotation to the root view controller instead of the top view controlller. If you want an individual view's rotation to behave differently than other views in the stack, you need to write a specific case for it in the root view controller.