My app is a UITabBarController --> UINavigationController --> UITableViewController --> UIViewController.
I want to do 2 things:
Prevent my tableview from rotating, I want it to always stay portrait.
FORCE & Allow my UIViewcontroller to rotate landscapeleft.
What I know:
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?
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 :)
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
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);
}
Responce
It should not be confused UIDeviceOrientation and interface orientation here is my solution
Appdelegate.h
@property () UIInterfaceOrientationMask restrictRotation;
AppDelegate.m
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
UIInterfaceOrientationMask restrictionOrientation = 0;
if (_restrictRotation == 0)
return UIInterfaceOrientationMaskAll;
UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
switch (currentOrientation)
{
case UIDeviceOrientationPortrait:
if (!(UIInterfaceOrientationMaskPortrait & _restrictRotation))
restrictionOrientation = UIInterfaceOrientationMaskAll;
else
restrictionOrientation = UIInterfaceOrientationMaskPortrait;
break;
case UIDeviceOrientationPortraitUpsideDown:
if (!(UIInterfaceOrientationMaskPortraitUpsideDown & _restrictRotation))
restrictionOrientation = UIInterfaceOrientationMaskAll;
else
restrictionOrientation = UIInterfaceOrientationMaskPortrait;
break;
case UIDeviceOrientationLandscapeLeft:
if (!(UIInterfaceOrientationMaskLandscapeLeft & _restrictRotation))
restrictionOrientation = UIInterfaceOrientationMaskAll;
else
restrictionOrientation = UIInterfaceOrientationMaskPortrait;
break;
case UIDeviceOrientationLandscapeRight:
if (!(UIInterfaceOrientationMaskLandscapeRight & _restrictRotation))
restrictionOrientation = UIInterfaceOrientationMaskAll;
else
restrictionOrientation = UIInterfaceOrientationMaskPortrait;
break;
case UIDeviceOrientationUnknown:
if (!(UIInterfaceOrientationUnknown & _restrictRotation))
restrictionOrientation = UIInterfaceOrientationMaskAll;
else
restrictionOrientation = UIInterfaceOrientationMaskPortrait;
break;
default:
NSLog(@"Unknown orientation");
break;
}
return restrictionOrientation;
}
In each vc add the function
-(void) restrictRotation:(UIInterfaceOrientationMask) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
viewDidAppear
//
// Set vc orientation
//
[self restrictRotation:UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight];
or what you want.
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationPortrait] forKey:@"orientation"];
or what you want.