Handling autorotation for one view controller in iOS7

19,216

Solution 1

You need to set the plist value to all possible values, then limit them as you see fit (in the Navigation Controllers and TabBar Controllers. From the UIViewController class description:

In iOS 6 and later, your app supports the interface orientations defined in your app’s Info.plist file. A view controller can override the supportedInterfaceOrientations method to limit the list of supported orientations. Typically, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen; child view controllers use the portion of the window provided for them by their parent view controller and no longer participate directly in decisions about what rotations are supported. The intersection of the app’s orientation mask and the view controller’s orientation mask is used to determine which orientations a view controller can be rotated into.

Solution 2

In my case, I had a new iOS7 app with about 30 view controllers created already. I needed auto rotation on just a single modal view controller. I didn't want to have to update the preexisting view controllers.

I selected the orientations I wanted in the plist:

select orientations

Then I added a category to my app delegate on UIViewController:

@implementation UIViewController (rotate)
   -(BOOL)shouldAutorotate {
      return NO;
   }
@end

Then in the single modal view controller I WANTED to rotate I added this method:

-(BOOL)shouldAutorotate {
      return YES;
}

I also discovered, that if my view controller wasn't a modal VC I would need to add category methods on UINavigationController instead, for all VCs that were subsequent to the root view controller, as part of the navigation stack of view controllers - similar to this: https://stackoverflow.com/a/20283331/396429

Solution 3

Simple but it work very fine. IOS 7.1 and 8

AppDelegate.h

@property () BOOL restrictRotation;

AppDelegate.m

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
    return UIInterfaceOrientationMaskPortrait;
else
    return UIInterfaceOrientationMaskAll;
}

ViewController

-(void) restrictRotation:(BOOL) restriction
{
    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    appDelegate.restrictRotation = restriction;
}

viewDidLoad

[self restrictRotation:YES]; or NO

Solution 4

I've faced such problem - had only one landscape view in my app. I've used below code to to handle that.

#import "objc/message.h"
-(void)viewWillAppear:(BOOL)animated{

objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeLeft);
}
Share:
19,216

Related videos on Youtube

djibouti33
Author by

djibouti33

Updated on June 04, 2022

Comments

  • djibouti33
    djibouti33 about 2 years

    I've read many answers on SO but I can't seem to get autorotation working on iOS7.

    I only need one view controller to rotate, so I don't want to set rotation settings in my Info.plist.

    As I understand Apple's documentation, a single view controller can override global rotations settings (from Info.plist) by simply overriding two methods. Info.plist is set to only allow Portrait, and my view controller implements the following methods:

    - (NSUInteger)supportedInterfaceOrientations
    {
        NSLog(@"%s", __PRETTY_FUNCTION__);
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    
    - (BOOL)shouldAutorotate
    {
        NSLog(@"%s", __PRETTY_FUNCTION__);
        return true;
    }
    

    I'm seeing those NSLog statements upon rotation but nothing rotates.

    If I do configure Info.plist with the proper rotation settings, my view will rotate, but not if I try and rely on my view controller.

    Not sure if it matters, but the view I'm trying to rotate is from a .xib using auto layout.

    Also, my ViewController is being presented modally and is contained in a navigation controller. I've tried just presenting the view controller by itself and that doesn't work. I've also tried adding a category to UINavigationController to get it's autorotation directions from it's topViewController.

    • Giorgio Barchiesi
      Giorgio Barchiesi over 10 years
      Same problem; in addition, I would like my app to be iOS5 compatible, so I can't use supportedInterfaceOrientations. I am using the other two functions: shouldAutorotate (returning NO) and shouldAutorotateToInterfaceOrientation (although deprecated). They are not even called! It appears there is no way out!
    • Giorgio Barchiesi
      Giorgio Barchiesi over 10 years
      I have finally given up... reviewed my xib so that the view appears in a somewhat reasonable way also in landscape orientation... :-(
  • jgvb
    jgvb over 10 years
    So you put the shouldautorotate and supportedinterfaceorientations in the view controller before the one you want to rotate one specific way or what?
  • Stoto
    Stoto almost 10 years
    You should not use categories to override methods. The clean way of doing the exact same thing is creating a base class for all your UIViewControllers and override the method there.
  • Nate Flink
    Nate Flink almost 10 years
    The whole point of my answer is to show how the objective is achievable without subclassing UIViewController. In some cases it isn't practical to do so
  • igrek
    igrek almost 10 years
    @Nate, the whole point of your answer is incorrect, category cannot be used for this since your case is a particular one, when it works. When you override a method using a category there is no guarantee that it will actually override it, it can still pick the old one.
  • igrek
    igrek almost 10 years
    refer to stackoverflow.com/questions/5272451/… for more details
  • Burf2000
    Burf2000 over 9 years
    Love it! hack and slash
  • Jeremy Luisetti
    Jeremy Luisetti over 8 years
    That is the clever solution i find around there. i may add that if in the same stack, one view controller is not restricted, the rest of the view controller should have [self restrictRotation:YES]; in the viewWillAppear (for when you push back button.) thank you Alan ! you're the best.