Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I restrict orientation per view controller in iOS7 in a navigation controller hierarchy

My app is a UITabBarController --> UINavigationController --> UITableViewController --> UIViewController.

I want to do 2 things:

  1. Prevent my tableview from rotating, I want it to always stay portrait.

  2. FORCE & Allow my UIViewcontroller to rotate landscapeleft.

What I know:

  1. I understand that the viewcontroller at the top of the hierarchy controls rotation. This would be my UITabBarController? Or rather its only viewcontroller which would be at objectIndex:0?

  2. My project settings allow for Portrait, LL and LR rotations. Im thinking this is the pattern I need to follow in order to solve this is allow ALL at the top level to rotate and then control each vc individually, correct?

This is what I have found so far in SO.

So for my top hierarchy, i set the project settings to allow rotation to Portrait, LL and LR.

and then in my tableviewcontroller which i dont want to rotate:

-(BOOL)shouldAutorotate{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

and finally in my uiviewcontroller which I want to rotate:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

-(BOOL)shouldAutorotate{
    return YES;
}

However this does not work. I can rotate both in any direction. I also dont know how to force rotation LL when I get to my uivc which is called from a modal segue from my tablevc.

Any help understanding this mess would be greatly appreciated :)

like image 528
marciokoko Avatar asked Dec 12 '13 14:12

marciokoko


2 Answers

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
like image 82
Alan10977 Avatar answered Nov 16 '22 16:11

Alan10977


Ok, here it is. kinda complicated.

Project Settings must allow P, LL & LR

Storyboard is a UINavController with a UITableViewController with a push bar button segue to a UIViewController.

All scenes in storyboard must have inferred as orientation in simulated metrics. Just saying, cause after a while i had them all with different settings after testing so much.

Must have a Class for NavController, TableViewController and the given UIVController. My app started out as Single view, then I dragged in a UITVC and finally embedded the UITVC in a UINVC. Then I connected the UIVC to the UITVC bar button item I dragged in via push segue.

Set apps window.rootvc to the navVC, your top hierarchy vc (don't forget to set that ID in storyboards or it'll crash of course):

    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
    UINavigationController *myNavC = (UINavigationController*)[mainStoryboard instantiateViewControllerWithIdentifier:@"MainNav"];
    self.window.rootViewController = myNavC;

Tell big boss UINVC everyone can rotate:

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

    - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
          return self.topViewController.supportedInterfaceOrientations;    
    }

Restrict tablevc so it won't rotate:

    - (BOOL)shouldAutorotate { return NO; }

    - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
        return (UIInterfaceOrientationMaskPortrait); 
    }

Allow last UIVC to rotate:

    - (BOOL)shouldAutorotate { return YES; }

    - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
        return (UIInterfaceOrientationMaskAllButUpsideDown);    
    }
like image 37
marciokoko Avatar answered Nov 16 '22 15:11

marciokoko