NavigationController clicked ViewControllers will not autorotate

I'm having difficulty setting up the navigation controller correctly. The display will autorotate on the initial view (the root view controller), but it will not rotate on any new views that are clicked. It retains the orientation of the view when the original view was clicked.

In my application delegate, I have a navigation controller and click it.

[window addSubview:navigationController.view]; [window makeKeyAndVisible]; 

In the root view controller, I enable all orientations and push other views onto the controller stack.

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } ParkingListController *parklc = [[ParkingListController alloc] autorelease]; [[self navigationController] pushViewController:parklc animated:YES]; 

I see: "Yes, we must!" It is registered once when a new view is loaded, but it does not work when the device is actually rotated.

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { NSLog(@"Yes, we should!"); return YES; } 

I have no init overrides, and info.plist lists all four orientations.

What am I missing? Thanks!

EDIT 2011-07-07:

Strange map display, which is clicked when you select an item from the table view, does autorotation! Why can it rotate when the view of the table from which it is derived cannot?

+2
source share
4 answers

You are using a UINavigationController and it must return true for rotation. Extend the UINavigationController and use the extended class in the interface builder.

 #import <Foundation/Foundation.h> @interface IRUINavigationController : UINavigationController { } @end #import "IRUINavigationController.h" @implementation IRUINavigationController - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ [self.visibleViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } @end 

I used this many projects and it works.

+4
source

Have you guaranteed that shouldAutorotateToInterfaceOrientation of ParkingListController also returns YES?

0
source

I would suggest two things:

  • make sure all your UIViewController 's shouldAutorotateToInterfaceOrientation return YES;

  • put the log message in willRotateToInterfaceOrientation to make sure that the views are responsive to the rotation of the device; shouldAutorotateToInterfaceOrientation is a method that can be invoked in unpredictable ways using the framework (i.e. it is not always invoked during autorotation).

In addition, it should work.

0
source

Each view controller inserted in the navigation controller stack must support the same orientation. This means that some view controllers cannot support only portrait, while others only support landscape. In other words, all view managers on the same stack of the navigation controller should return the same in the delegate:

 (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

But this is a simple solution! Here is an example of a transition from portrait to landscape. Here are the steps to do this, and below is the code to support it.

  • Create a "fake view controller" that will be root in the sub-navigation controller. This view controller must support terrain.
  • Create a new instance of the UINavigationController, add an instance of the "fake view controller" as root and an instance of your landscape view controller as the second view controller.
  • Present an instance of UINavigationController as modal from the parent view controller

First create a new view controller (FakeRootViewController) with this code:

 @interface FakeRootViewController : UIViewController @property (strong, nonatomic) UINavigationController* parentNavigationController; @end @implementation FaceRootViewController @synthesize parentNavigationController; // viewWillAppear is called when we touch the back button on the navigation bar (void)viewWillAppear:(BOOL)animated { // Remove our self from modal view though the parent view controller [parentNavigationController dismissModalViewControllerAnimated:YES]; } (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation)); } 

Here is the code to represent the view controller that you want to show in landscape mode:

 FakeRootViewController* fakeRootViewController = [[FakeRootViewController alloc] init];[fakeRootViewController.navigationItem setBackBarButtonItem:backButton]; // Set back button // The parent navigation controller is the one containing the view controllers in portrait mode. fakeRootViewController.parentNavigationController = parentNavigationController; UINavigationController* subNavigationController = // Initialize this the same way you have initialized your parent navigation controller. UIViewController* landscapeViewController = // Initialize the landscape view controller [subNavigationController setViewControllers: [NSArray arrayWithObjects:fakeRootViewController, landscapeViewController, nil] animated:NO]; [_navigationController presentModalViewController:subNavigationController animated:YES]; 

Remember that LandscapeViewController must also have this implementation:

 (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation)); } 
0
source

All Articles