0

At this time I am halfway to keeping ViewControllerA in portrait mode. To do this, I am using preferredInterfaceOrientationForPresentation

This ensures that ViewControllerA, when I push to it, will be in portrait mode. However, if I push from ViewControllerA to ViewControllerB, switch to landscape mode in ViewControllerB, and then dismiss back to ViewControllerA, ViewControllerA can be presented in landscape mode. My desire is to continue multiple orientation support of ViewControllerB, but force ViewControllerA to autorotate to portrait.

Also, for some reason shouldAutorotate does not appear to be getting called in ViewControllerA. Perhaps addressing this could fix the entire issue?

UINavigationController+Orientation.h Category

@interface UINavigationController (Orientation)

- (BOOL)shouldAutorotate;
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;

@end

UINavigationController+Orientation.m Category

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

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

ViewControllerA.m

- (BOOL)shouldAutorotate {
    return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}
Jeremy H
  • 452
  • 7
  • 20

2 Answers2

1

I faced the same problem. My solution is below, and its in a released app.

I added a public property called allowViewRotation to my AppDelegate.h:

@property (assign, nonatomic) BOOL allowViewRotation;

Then I've implemented the following call in my AppDelegate.m file:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { // if iPad
        return UIInterfaceOrientationMaskAll;
    }

    if (self.allowViewRotation) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    else {
        return UIInterfaceOrientationMaskPortrait;
    }
}

Now in ViewControllerA set allowViewRotation property to NO

((AppDelegate*)[UIApplication sharedApplication].delegate).allowViewRotation = NO;

And in ViewControllerB set allowViewRotation property to YES

((AppDelegate*)[UIApplication sharedApplication].delegate).allowViewRotation = YES;

Note: make sure that you enable the proper device orientation in Deployment Info

enter image description here

hope this helps!

Mike
  • 1,313
  • 14
  • 17
  • It still does not seem to be working. And I am using the same orientation settings as you did (all but upside-down). I tried using **((AppDelegate*)[UIApplication sharedApplication].delegate).allowViewRotation** in both viewDidLoad and viewWillAppear, but both did not prevent ViewControllerA from loading as landscape upon dismissing back to it. – Jeremy H Sep 10 '14 at 16:50
  • make sure the default is allowViewRotation=NO. and put the YES/NO changing inside of ViewControllerB's **viewWillAppear:** and **viewWillDisappear:** `-(void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; appDelegate.allowViewRotation = YES; } -(void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; appDelegate.allowViewRotation = NO; }` – Mike Sep 10 '14 at 17:43
  • try to call attemptRotationToDeviceOrientation to force the app to call **supportedInterfaceOrientationsForWindow** https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation – Mike Sep 10 '14 at 17:53
  • Thanks for the all quick replies! I tried to call **attemptRotationToDeviceOrientation**, but again to no avail. As for **viewWillAppear** and *viewWillDisappear**, I have tried the setup you mentioned, along with variations of it. Yet it doesn't seem to be going through. If ViewControllerA is in landscape (which I don't want), it will switch to portrait if the phone is moved into that orientation and then lock it from there. But that is currently as close as I can get it. – Jeremy H Sep 10 '14 at 19:29
  • yea, there used to be a call to UIDevice to force orientation change, but it was a private call and recently in iOS7 its no longer there. Sorry I couldn't be more helpful. – Mike Sep 11 '14 at 14:53
0

Alright, I was able to get things working!

So one thing in my situation that was making things difficult was I had two segments; one took place before logging in (did not have NavController) an the other was post login (did have NavController). Perhaps I broke a best practice guideline there?

Anyways, Teo C.'s answer is the one that helped me: iOS 7. Change page orientation only for one view controller

I made this discovery by making a new blank project. If you are having trouble with forcing orientations, you can look at the example I made https://github.com/jerherrero/Force-Orientations

Community
  • 1
  • 1
Jeremy H
  • 452
  • 7
  • 20