10
votes

All view controllers in my app are working only in portrait orientation except one which can be portrait or landscape oriented.

I have some usage scenario like following:

  1. I push controller which works in both orientations to UITabBarController
  2. User change orientation from portait to landscape
  3. User press "back button"

After these actions application remains in landscape orientation and does not change it automatically to portrait.

I control view controller orientation using supportedInterfaceOrientations (I use iOS 6.0). What I do wrong? How can I get correct behaviour when application automatically change orientation to allowed when user press back button? Thank you for answer!

4
This scenario is explained in the Apple documentation here.Dheeraj Vepakomma
@DheerajV.S. Link is dead.Borzh

4 Answers

2
votes

In iOS 6 (and possibly earlier), if a view controller is offscreen when the device rotates, it does not get any notification. Nor does it get sent willAnimateRotationToInterfaceOrientation:duration: when it becomes the top view controller.

You need to keep track of the current orientation of the view controller and check the device orientation in viewWillAppear:. If they are different, you can use willAnimateRotationToInterfaceOrientation:duration: to set it correctly.

Since this is something you are likely to do a lot, you may want to create a generic superclass that your view controllers inherit from.

A typical solutions is:

@implementation MyHandlesOffscreenRotationController
{
    BOOL   isShowingPortrait;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    isShowingPortrait = UIInterfaceOrientationIsPortrait(
                        [[UIApplication sharedApplication] statusBarOrientation]);
}


- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

        BOOL currIsPortrait = UIInterfaceOrientationIsPortrait(
                              [[UIApplication sharedApplication] statusBarOrientation]);

    if ((isShowingPortrait && !currIsPortrait) ||
        (!isShowingPortrait && currIsPortrait)) {
        [self willAnimateRotationToInterfaceOrientation:
                [[UIApplication sharedApplication] statusBarOrientation]
                                              duration:0.0f];
    }
}

@end
2
votes

Just override -(BOOL)shouldAutoRotate and - (NSUInteger)supportedInterfaceOrientations inside a UINavigationController category, then ViewController will force rotate to its supported orientation after pop from other ViewController.

@implementation UINavigationController (Rotate)

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

- (NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations];
}

@end
2
votes

iOS 9 and above

At the time of pop just write the below-mentioned code in your viewWillAppear method.

[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]forKey:@"orientation"];

With this, your view will appear in portrait mode.

0
votes

P.L. has a nice solution in this topic: Present and instantly dismiss an empty modal view controller which allows only portrait | landscape

How to change the device orientation programmatically in iOS 6