5
votes

So like many others, I ran into the problem of only having one or two viewcontrollers support both portrait and landscape interface orientations, in an otherwise portrait only app. Everything worked fine prior to iOS 6, but suddenly autorotating stopped working. Thanks to some great questions here, I was able to resolve that issue by having the initial navController return the individual topViewController's preference for shouldAutorotate via:

    - (BOOL)shouldAutorotate
{
    return  self.topViewController.shouldAutorotate;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

However, I have stumbled onto a new problem. the root vc (viewController A) should NOT autorotate and should only support portrait. ViewController B in the nav stack supports portrait and landscape. If I am in viewController B, and am in landscape, and touch "back" to pop the view back to viewController A... vc A loads in landscape, which it is not supposed to even support, and wont rotate back to portrait because shouldAutorotate for vc A is set to NO...

Any ideas on how to deal with this would be greatly appreciated. My initial thought was to override vc B's "back" button with a manual method that first force rotates back to portrait if the view is in landscape... then pops the viewcontroller back to vc A... but I cant figure out how to force a rotation programatically. Any ideas?

here are the interface methods in vc A:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return NO;
}

-(BOOL)shouldAutorotate
{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

and here is what they are in vc B:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}
2
Exactly the same issue. A workaround is to set to status bar orientation in portrait for vc Aand manually rotate the view with MakeRotation. Its works but I get a wrong layout then when pushing vc B again. Someone know if there a method that will force again the vc A in portrait orientation?nicolas
Yes, the same issue for me too, but I didn't set my vcA not to rotate, so when the user put his device to portrait, the view rotate correctly. I didn't find any acceptable workaround... Moreover Apple does not agree with asking the user to rotate their devices...dulgan
I've ran into the same issue with MPMoviePlayerViewController which must maintain allButPortraitUpsideDown orientations but the rest of app is portrait only.still cant find the solution. Daniel have you fixed your problem?Stas

2 Answers

1
votes

In vcA set

-(BOOL)shouldAutorotate
{
  return YES;
}

But keep

-(NSUInteger)supportedInterfaceOrientations
{
  return UIInterfaceOrientationPortrait;
}

Then the view will rotate back to the (only) supported orientation when you return from vcB

0
votes

The problem is that all container view controllers (Tab Bar Controller, Navigation Controller etc.) support all those interface orientations that you give in your plist file. When the system asks for the supported interface orientations the root view controller's settings and method implementations override it's children's.

In this case the Navigation Controller supports both landscape and portrait and when the B View controller pops, although the system asks for A's interface orientations, it will ask it's root view controller too and that will be the "winner" and since the Navigation Controller supports landscape, it stays in landscape despite that A supports portrait only.

One solution is, that you subclass the root view controller and change it's rotation methods dynamically as needed. When only portait is needed your root's implementation should return portait only and when both orientations are available, then your root should return both.