Force portrait mode when dismissing a presented view controller
Asked Answered
B

2

6

I have a presented view-controller that is supporting all interface orientations. However, the presenting view controller only should support portrait mode.

So far so good.

However, in iOS8, when I dismiss the view controller WHILE in landscape mode, landscape mode stays. And since I have shouldAutorotate set to NO it an never rotate back.

Question is, how can I force the presenting VC to return to portrait?

I currently have this workaround implemented:

- (BOOL)shouldAutorotate
{
  if ([self interfaceOrientation] != UIInterfaceOrientationPortrait)
  {
    return YES;
  }
  else
  {
    return NO;
  } 
}

It allows to move the device into portrait and it will stay here, since after it's portrait autorotate is disable.

But it looks ugly until the user rotates his phone.

How to force it?

Bop answered 20/9, 2014 at 16:21 Comment(0)
P
2

We had the exactly same problem. You can rotate it programmatically by the code -

if ([UIApplication sharedApplication].statusBarOrientation != UIInterfaceOrientationPortrait) {
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

There are 2 possible options -

1) before you dismiss the presented viewController, rotate to portrait if needed

2) after you dismiss, rotate to portrait in the "viewDidAppear" of the presenting viewController.

One issue with this, is that you can't pass a completion block, but you can use the next callback in iOS8:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    if (self.needToDismissAfterRotatation)
        self.needToDismissAfterRotatation = NO;
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
            // dismiss
        }];
    }
}

By the way, in iOS8 apple did a huge change in the way the screen rotates, when the app rotates, the screen rotates, and all the elements in the UIWindow rotates as well, this is why when the presented viewController rotates to landscape, also the presenting viewController rotates, even if it only supports portrait...

We struggled with this issue for many days, finally we came up with a solution to put the presented viewController in a new UIWindow, and this way it keeps the presenting viewController in portrait all the time

example project for that: "modalViewController" in UIWindow


Plowshare answered 27/2, 2015 at 5:54 Comment(2)
Sir, you saved my lifeConditional
@PaulBerg yay! Glad that 2015 me could help :)Plowshare
R
0

This code will force the UI back to portrait, assuming that the view controller you're trying to force portrait was already the root view controller (if it wasn't already the root, this code will restore the root view controller but not any other view controllers that have been pushed onto it):

UIInterfaceOrientation orientation = [[UIApplication 
    sharedApplication] statusBarOrientation];

if (orientation != UIInterfaceOrientationPortrait) {

    // HACK: setting the root view controller to nil and back again "resets" 
    // the navigation bar to the correct orientation
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    UIViewController *vc = window.rootViewController;
    window.rootViewController = nil;
    window.rootViewController = vc;

}

It's not very pretty as it makes an abrupt jump after the top level view controller has been dismissed, but it's better than having it left in landscape.

Rabies answered 11/11, 2014 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.