In my app I have multiple views, some views need to support both portrait and landscape, while other views need to support portrait only. Thus, in the project summary, I ha
This code worked for me:
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
iPhone/iPad App Orientation check out my own answer
As stated by others if you're using a UINavigationController and you want to customize various views you'll want to subclass the UINavigationController and make sure you have these two components:
@implementation CustomNavigationController
// -------------------------------------------------------------------------------
// supportedInterfaceOrientations:
// Overridden to return the supportedInterfaceOrientations of the view controller
// at the top of the navigation stack.
// By default, UIViewController (and thus, UINavigationController) always returns
// UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
// -------------------------------------------------------------------------------
// shouldAutorotate
// Overridden to return the shouldAutorotate value of the view controller
// at the top of the navigation stack.
// By default, UIViewController (and thus, UINavigationController) always returns
// YES when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
Then in any view that is a portrait only you would include:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And in any view that is everything but upside down:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
I have the same situation as you. I know you already accepted an answer, but I thought I'd add another one anyway. This is the way I understand the new version of the rotation system to work. The root view controller is the only view controller to ever be called. The reasoning, I believe, is that with child view controllers it doesn't make sense often to rotate their views since they will just stay within the frame of the root view controller anyway.
So, what happens. First shouldAutorotate
is called on the root view controller. If NO
is returned then everything stops. If YES
is returned then the supportedInterfaceOrientations
method is invoked. If the interface orientation is confirmed in this method and the global supported orientations from either the Info.plist or the application delegate, then the view will rotate. Before the rotation the shouldAutomaticallyForwardRotationMethods
method is queried. If YES
(the default), then all children will receive the will
and didRotateTo...
methods as well as the parent (and they in turn will forward it to their children).
My solution (until there is a more eloquent one) is to query the last child view controller during the supportedInterfaceOrientations
method and return its value. This lets me rotate some areas while keeping others portrait only. I realize it is fragile, but I don't see another way that doesn't involve complicating things with event calls, callbacks, etc.
The best way I think is to do a Category rather than subclassing UINavigationController
or UITabbarController
your UINavigationController+Rotation.h
#import <UIKit/UIKit.h>
@interface UINavigationController (Rotation)
@end
your UINavigationController+Rotation.m
#import "UINavigationController+Rotation.h"
@implementation UINavigationController (Rotation)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
Try to make all your controller import this category and this work like a charm. You can even make a controller not rotating and pushing another controller that will rotate.
my solution : subclassed UINavigationController
and set it as window.rootViewController
the top viewcontroller of the hierarchy will take control of the orientation , some code examples : subclassed UINavigationController
If you are using UINavigationController
, you have to implement shouldAutorotate
and supportedInterfaceOrientations
in subclass of UINavigationController
.
These are able to control by two steps, if shouldAutorotate
returns YES then effective supportedInterfaceOrientations
. It's a very nice combination.
This example, my mostly views are Portrait except CoverFlowView and PreviewView. The CoverFlowView transfer to PreviewView, PreviewView wants to follow CoverFlowCView's rotation.
@implementation MyNavigationController
-(BOOL)shouldAutorotate
{
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"PreviewView")])
return NO;
else
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"CoverFlowView")])
return UIInterfaceOrientationMaskAllButUpsideDown;
else
return UIInterfaceOrientationMaskPortrait;
}
...
@end