views:

1011

answers:

3

My iPhone application is displaying some odd behavior when run on the iPad with respect to supporting orientation changes.

The app starts up with a view controller (call it view A for the sake of argument) and navigation controller, and shouldAutorotateToInterfaceOrientation is returning YES for portrait only. Onto the navigation controller, I push a view controller (view B) that also returns YES for portrait only. Then, I push another view controller (view C) onto the nav controller that supports all rotations and adjusts the items on screen based on the orientation to rotate to.

When this is run on the iPhone simulator and device, if you rotate to landscape on view C and then tap the back button to return to view B, it does the right thing and shifts view B back to portrait mode. (In the simulator, it even rotates the simulator back to portrait automagically.)

The problem I am experiencing is that, when I do this exact same sequence of events on the iPad simulator and device, the view B that appears is not rotated back to portrait, and the nav controller still shows the information for view C. Then, I tap on the back button, and the view stays the same but the nav controller shows normal for view B (but all still in landscape mode). Then, if I tap the back button again, view A appears under the view B nav bar items, and finally tapping back again puts me on view A with nav bar A items.

If I go to view B on the iPad and start to rotate around, shouldAutorotateToInterfaceOrientation fires with NO until I reach portrait mode, and then all returns to normal.

The application is being built with the latest released version of the iPhone SDK, and has build settings as follows: Base SDK of iPhone Simulator 4.0, Targeted Device Family of iPhone, iPhone OS Deployment Target of iPhone OS 3.1.3.

Any ideas?

+2  A: 

Apple states:

Case: All child view controllers in your UITabBarController or UINavigationController do not agree on a common orientation set.

Response: To make sure that all your child view controllers rotate correctly, you must implement shouldAutorotateToInterfaceOrientation for each view controller representing each tab or navigation level. Each must agree on the same orientation for that rotate to occur. That is, they all should return YES for the same orientation positions.

http://developer.apple.com/iphone/library/qa/qa2010/qa1688.html

You may be able to set device orientation within the navigation controller instead of within individual views. Then you could check which view is on the stack and rotate based on the result. In this way, the navigation controller handles all orientation as well.

iWasRobbed
that's not the problem. please read the question carefully. There's a real difference between iPhone and iPad, how they handle this issue...
Konstantin
I understand the problem, I was just passing on Apple's guidance :) If you feel it is a bug in the simulator, you should file a radar with Apple about it. A lot of people use navigation controllers with orientation, but I can't seem to find any information on others having this same issue even though 3.2 has been out for a long time now.
iWasRobbed
I think this does apply to your case. Your view C supports all orientations while A and B support only portrait. Apple's QA1688 says that all child view controllers under a UINavigationController have to agree on a comment set of orientations. I had the same problem (vc didn't agree on orientations) in [this question](http://stackoverflow.com/questions/3086684).
progrmr
A: 

Here is some code i'm using to prevent that error:

- (void)viewDidLoad {  
    if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
        self.view.bounds = CGRectMake(0.0, 0.0, 480, 320);
    }
    [UIView commitAnimations];
}

and

- (void)viewDidLoad {
    if (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        self.view.transform = CGAffineTransformIdentity;
        self.view.transform = CGAffineTransformMakeRotation(-(M_PI / 2));
        self.view.bounds = CGRectMake(0, 0, 320, 480);;
    }
    [UIView commitAnimations];
}

Based on what orientation the device is in, you will need to modify some of the code.

NSArray
Why set transform twice?
progrmr
The first one sets the type of transformation(identity) and the second one does the transformation.Also shouldAutoRotateToInterfaceOrientation says to rotate if the device is in that orientation. If the device is in landscape, then the interface won't rotate unless it is in portrait. The code I submitted is for the iPhone(320 and 480), but if the orientation of the device is lanscape, the view will look like it is in portrait, making the user tilt the device to set it to portrait(vice versa).
NSArray
A: 

I have pretty much the same problem with Navigation Bar. And it happens only in landscape orientation though all view controllers supports all orientations.

Kostiantyn Sokolinskyi
You must inherit from UITabBarController and its shouldAutorotateToInterfaceOrientation method must return YES for the orientations you need. In such a case your view controllers belonging to tabbar controller will rotate automatically but to make them work fully correct (avoid nav bar bugs) they also must return YES from shouldAutorotateToInterfaceOrientation method. Strange enough that you override shouldAutorotateToInterfaceOrientation method in each UIViewController subclass (or a superclass for your view controllers) - overriding it in a category doesn't work.
Kostiantyn Sokolinskyi