I´m having this issue with iOS 6 SDK: I´m having some views that should be allowed to rotate (e.g. a videoview), and some that don´t.
Now I understand I have to check all orientations in the app´s Info.plist and then sort out in each ViewController, what should happen. But it doesn´t work! The app always rotates to the orientations, that are given in the Info.plist.
Info.plist:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
any ViewController that shouldn´t be allowed to rotate:
//deprecated
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
Observation: App rotates to landscape and portrait orientation. Any ideas why or what I´m doing wrong?
Cheers,
Marc
Edit: My latest findings also indicate, that if you want to have rotation at some point in your app, you have to activate all four rotation directions in your project settings or Info.plist. An alternative to this is to override
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
in your AppDelegate, which overrides the Info.plist. It isn´t possible anymore to set only Portrait in your Info.plist and then having rotation in some ViewController by overriding shouldAutorotateToInterfaceOrientation or supportedInterfaceOrientations.
If your ViewController is a child of a UINavigationController or UITabBarController, then it is the parent that is your problem. You might need to subclass that parent view controller, just overriding those InterfaceOrientation methods as you've shown in your question
EDIT:
Example for portrait only TabBarController
#interface MyTabBarController : UITabBarController
{
}
#end
#implementation MyTabBarController
// put your shouldAutorotateToInterfaceOrientation and other overrides here
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
#end
Adding to CSmith's answer above, the following code in a UINavigationController subclass allows delegation to the top view controller in the way that I expected this to work in the first place:
- (BOOL)shouldAutorotate;
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[self topViewController] respondsToSelector:#selector(supportedInterfaceOrientations)])
return [[self topViewController] supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
Here's another alternative to CSmith's approach.
If you want to replicate the pre-iOS 6 behaviour where all the views in the navigation stack / tab bar have to agree on an allowable set of orientations, put this in your subclass of UITabBarController or UINavigationController:
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger orientations = [super supportedInterfaceOrientations];
for (UIViewController *controller in self.viewControllers)
orientations = orientations & [controller supportedInterfaceOrientations];
return orientations;
}
Try to add this category:
#interface UINavigationController(InterfaceOrientation)
#end
#implementation UINavigationController(InterfaceOrientation)
- (NSUInteger) supportedInterfaceOrientations {
if (self.viewControllers.count > 0)
return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations];
else
return UIInterfaceOrientationMaskAll;
}
#end
For people using UINavigationController and Swift, you can add this extension to your project. After that, navigation controllers delegate the control to their child controller.
extension UINavigationController {
override public func supportedInterfaceOrientations()
-> UIInterfaceOrientationMask {
if let ctrl = topViewController {
return ctrl.supportedInterfaceOrientations()
}
return super.supportedInterfaceOrientations()
}
override public func shouldAutorotate() -> Bool {
if let ctrl = topViewController {
return ctrl.shouldAutorotate()
}
return super.shouldAutorotate()
}
}
Further addition to #CSmith and #EvanSchoenberg.
If you have some views that rotate, and some views that don't, you must create a custom instance of the UITabBarController, yet still let each UIViewController decide.
- (BOOL)shouldAutorotate;
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
UIViewController * top;
UIViewController * tab = self.selectedViewController;
if([tab isKindOfClass:
([UINavigationController class])]) {
top = [((UINavigationController *)tab)
topViewController];
}
if ([top respondsToSelector:#selector(supportedInterfaceOrientations)])
return [top supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
#Alvivi's answer updated for Swift 4.
extension UINavigationController {
// Look for the supportedInterfaceOrientations of the topViewController
// Otherwise, viewController will rotate irrespective of the value returned by the ViewController
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if let ctrl = self.topViewController {
return ctrl.supportedInterfaceOrientations
}
return super.supportedInterfaceOrientations
}
// Look for the shouldAutorotate of the topViewController
// Otherwise, viewController will rotate irrespective of the value returned by the ViewController
override open var shouldAutorotate: Bool {
if let ctrl = self.topViewController {
return ctrl.shouldAutorotate
}
return super.shouldAutorotate
}
}
#Shimanski Artem's answer is good, but I think using the topmost (currently visible) controller is better solution:
#interface UINavigationController(InterfaceOrientation)
#end
#implementation UINavigationController(InterfaceOrientation)
- (NSUInteger) supportedInterfaceOrientations {
if (self.viewControllers.count > 0){
return [[self.viewControllers objectAtIndex:[self.viewControllers count] - 1] supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskAll;
}
#end
As an alternate option, in case you want to preserve pre-iOS6 rotation functionality in your app:
Here's a helpful bit of code on github that swizzles the method calls for iOS6 so that rotation works like it did on iOS4/iOS4. This really helped me, as I'm supporting a legacy app that really micro-manages its rotations. It would have been a lot of work to implement the changes required for iOS6. Kudos to the user who posted it.
https://gist.github.com/3725118
Related
I have a problem with orientations in my app. Assume that I have two views (with dedicated view controllers):
first should be displayed in portrait (it is displayed correctly)
second should be displayed in landscape (it is not displayed correctly)
It is coarctated and displayed in portrait (like in second image below).
When I rotate device horizontal and back to portrait everything is OK. But after pushing view it displays incorrectly (images below). How can I fix this?
I use CustomNavigationController whish inherits from UINavigatorControler and implements three methods:
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
return [self.topViewController shouldAutorotateToInterfaceOrientation:orientation];
}
In application delegate I initializing controller in this way:
self.navigationController = [[CustomNavigationController alloc] initWithRootViewController:self.viewController];
[self.window setRootViewController:self.navigationController];
First view controller implements orientation functions in this way:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationPortrait)
return YES;
return NO;
}
Second view controller implements orientation functions in this way:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationLandscapeRight)
return YES;
return NO;
}
hi declare a global variable BOOL isLandScape ;
initialize it as isLandScape=NO;
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if ((orientation == UIInterfaceOrientationLandscapeRight)||(orientation == UIInterfaceOrientationLandscapeLeft))
{
isLandScape=YES;
return YES;
}
else
{
isLandScape=NO;
return NO;
}
yourObject.frame=CGRectMake(isLandScape?0:0,isLandScape?0:0,isLandScape?1024:768,isLandScape?768:1024);
}
Check the question How to handle different orientations in iOS 6. See the answer there for a project example of exactly what you need.
Basically you need to embed a custom navigation controller in your viewcontroller (the one you want to rotate). Add the following method in this custom navigation controller (this if for landscape orientation but you can change to portrait too).
- (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
and add to your view controller that should rotate:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Be sure Portrait, Landscape Right and Landscape Left orientations are enabled in your project. Then, if you want to block some orientations for a particular window:
– application:supportedInterfaceOrientationsForWindow:
To do this You can use this function:
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
You can use this wherever you want, but in application delegate (in didFinishLaunchingWithOptions) i must put this code:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
It's works perfectly!
I have two UIViewControllers in my UINavigationController stack, in which i need to support portrait and landscape orientations for the first viewController alone and for the second viewController, i need portrait support alone and not landscape.
In ViewController1, I have implemented the following methods,
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self changeFrames:toInterfaceOrientation]; //changing frames for orientation accordingly
}
and in ViewController2:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Also in project target, i have set to support all the 4 orientations.
Looking for any kind of help to solve the above issue.
Thanks in Advance.
i am working on app. the orientation of app is landscape but after app run interface orientation of app change the interface and rotate. splash screen display in correct way (landscape).
i am using ios7 the app was code for ios5 i think there is some deprecated api issue e.g. shouldAutorotateToInterfaceOrientation bot called because this is no more available in latest ios
If you want all of our navigation controllers to respect the top view controller you can use a category so you don't have to go through and change a bunch of class names.
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
As a few of the comments point to, this is a quick fix to the problem. A better solution is subclass UINavigationController and put these methods there. A subclass also helps for supporting 6 and 7.
you have to set orintatoin in build seeting see image.
it will solve your Problem.
Try this:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
EDIT :
See the attached link, might be helpful for you.
i find solution the think which i do is.
step one
override my UInavigationcontroller by creating a category
step two
Replace
[self.window addSubview:[navigationController view]]; //OLD
With
[self.window setRootViewController:navigationController]; //NEW
use this in your Appdelegate.m
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
NSLog(#"Interface orientations");
if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPad ){
return UIInterfaceOrientationMaskLandScape;
}
else{
return UIInterfaceOrientationMaskPortrait;
}
}
It helped me..
My application runs in only landscape mode ! so I know UIImagePickerController presents only in portrait mode , so in iOS 6 , I had created a subclass of UIImagePickerController that forced UIImagePickerController to open in portrait mode:
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate {
return NO;
}
#end
//presenting picker controller :
UIImagePickerController *ipc = [[NonRotatingUIImagePickerController alloc]init];
ipc.delegate = self;
[self presentViewController:ipc animated:YES completion:nil];
This worked fine in iOS 6 , but now in iOS 7 my app does crash because of this :
2013-10-31 14:56:01.028 Medad[1731:60b] *** Terminating app due to
uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason:
'Supported orientations has no common orientation with the
application, and shouldAutorotate is returning YES'
This problem could be solved if I check Portrait in deployment info :
The problem is if I check this option my app does run in portrait too but I don't want it!
How can I solve this issue?
I have tested it and found that you should not handle the orientation via check box in target window as you shown in the above image because its your whole app orientation so please check all boxes to get all orientation supported. If you want some view in different orientations and some in different then you will have to handle it via coding in ViewController class by returning YES OR NO for orientation.
Here is my Sample. Which I made. Please check.
Below method will handle the orientation for ViewController
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
// Old Method
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
return NO;
}
else {
return YES;
}
}
So, Solution is: Make two custom class one for UIImagePickerController and another is for ViewController (For All ViewControllers) and just make them for specific orientation and use those class as super class of your UIImagePickerController and all ViewControllers respectively.
There is one simple solution to avoid changing the supported orientations of your app, and make the UIImagePickerController work correctly: return UIInterfaceOrientationMaskAll only when the picker has to be presented.
You can do it simply subclassing UIApplication and using these two methods:
- (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
UIViewController *topController = window.rootViewController;
if ([self hasPicker:topController])
return UIInterfaceOrientationMaskAll;
return [super supportedInterfaceOrientationsForWindow:window];
}
-(BOOL)hasPicker:(UIViewController *)controller
{
BOOL hasPicker = NO;
NSLog(#"Check Controller: %#", controller);
if ([controller isKindOfClass:[UIImagePickerController class]])
return YES;
for (UIViewController *child in controller.childViewControllers) {
hasPicker = [self hasPicker:child];
if (hasPicker)
return YES;
}
return NO;
}
In the first method, you are overriding the default supportedInterfaceOrientationsForWindows: method. Every time the method is called, you check all the view controllers in the hierarchy (through hasPicker:, a recursive method). If an UIImagePickerController is found, you return UIInterfaceOrientationMaskAll, otherwise you return the default setting of your app.
Another thing I suggest you: don't subclass UIImagePickerController, since Apple explicitly forbids it. Instead, use view controller containment as I did in this example:
Landscape Picker Example
NOTE: The example code works only with UIImagePickerController containment. If you subclass it and add it through presentViewController: you may have to adjust the behavior of the hasPicker: method. One other simple thing you can do: add an instance variable to your UIApplication subclass and set it when you show the picker, and unset when you dismiss
Another solution.
In every controller add, even to the controller that have the picker:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
return YES;
}
return NO;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
Add this to your custom picker controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
return YES;
}
return NO;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
In every controller add:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
return YES;
}
return NO;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
For the controller you have the picker:
Design this view with only Portrait orientation. So, it will have the same orientation of the picker. This view will be the only view with Portrait orientation while the others with landscape.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
return YES;
}
return NO;
}
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation==UIInterfaceOrientationPortrait) {
}
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
Other solutions will also crash in the views that have the picker since they don't return portrait orientation to handle the picker orientation. while not adding any code to this view controller will let this view to run in landscape and portrait.
So, my proposed solution that to run all the views in landscape and this one in portrait. having this view in portrait is more design logical to have the same orientation of the picker.
The following go into your custom picker:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
return YES;
}
return NO;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
You should also set in the subclass:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft ;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate {
return YES;
}
Now you can remove from the settings "Portrait"
[EDIT]
Since the UIImagePickerController can only be presented in Portrait (as per Apple doc), is possible to do the other way around, enabling portrait and landscape orientation, but fixing the orientation in landscape of everything but the picker controller. I made a little sample downloadable from here.
Actually i had the same problem and solved it in a different way...
Actually this was identified as a bug in IOS6 happens with ImageViewController which only supports Portrait orientation ... so i spent lot of time and found a way around the same....
hope this helps so first things first...
add a property in your AppDelegate.h
#property BOOL model;
then in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.model=NO;
return YES;
}
also add this method in AppDelegate.m
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(!self.model)
return UIInterfaceOrientationMaskLandscape; //or needed orientation
else
return UIInterfaceOrientationMaskAllButUpsideDown;
}
then in your view controller before presenting the imagepicker
implement this code...
AppDelegate *appdelegate=(AppDelegate*)[[UIApplication sharedApplication] delegate];
appdelegate.model=YES;
and then you just change the value when you came back after picking image , ie, delegate method
AppDelegate *appdelegate=(AppDelegate*)[[UIApplication sharedApplication] delegate];
appdelegate.model=NO;
I want to support iOS 6 rotation. Trouble is, I've been looking through a lot of documentation and stack overflow questions but have not found any even slightly in depth solutions. I've only seen that I should add these two methods to my view controller classes - however, if I'm not mistaken, they do not operate in the same way as the pre iOS 6 methods:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll; // use what is appropriate for you.
}
My app currently rotates in pre-iOS6 using the following code. Note that I use the interface orientation parameters to determine whether or not I'm going to push my view Controller. How do I implement this in the iOS 6 rotation delegates?
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
UIInterfaceOrientation toOrientation = self.interfaceOrientation;
if ( self.tabBarController.view.subviews.count >= 2 )
{
UIView *tabBar = [self.tabBarController.view.subviews objectAtIndex:1];
if(toOrientation != UIInterfaceOrientationLandscapeLeft && toOrientation != UIInterfaceOrientationLandscapeRight)
{
CUSTOM_DEBUG_LOG("\n\nRotated back to Portrait");
tabBar.hidden = FALSE;
}
}
}
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
CUSTOM_DEBUG_LOG("\nView going landscape");
ScrollViewController *s = [[ScrollViewController alloc] initWithNibName:#"ScrollViewController" bundle:nil];
[self.navigationController pushViewController:s animated:NO];
[s release];
self.tabBarController.tabBar.hidden = YES;
self.navigationController.navigationBar.hidden = YES;
}
}
Checkout this and this SO discussion.
[EDIT]
Yes the methods you mentioned aren't deprecated in iOS 6.0 and they will continue working. It's just the way Auto Rotation works have been changed. So far it was view controllers responsibility to decide whether they rotate or not but now RootViewController will decide whether their children should rotate or not. If you don't have rootviewcontroller setup then you have to add it to window and then put shouldAutoRotate and supportedInterfaceOrientations methods in the rootviewcontroller.
Parent Views now handle rotation in iOS 6. Subclass your nav controllers and add a bool
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait; // your rotation here
}
I may not have implemented the iOS6 rotation code correctly when I first posted the question.
I incorrectly thought that the willAnimateRotationToInterfaceOrientation function was deprecated in iOS6, leading me to believe that there was a new iOS rotation delegate with an orientation parameter. Turns out this is not the case, so my app sort of works.
The code I plugged into my app was just this:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
}
If you are using a UINavigationController, override shouldAutomaticallyForwardRotationMethods = YES property.
Then like Mark S said, also override shouldAutorotate and supportedInterfaceOrientations for the children VCs.