Reputation: 2207
I feel like my question is answered in iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates), but I'm not advanced enough to understand how to implement the responses.
I'm writing a tabbed application using iOS6, and I want one of the view controllers to rotate and the rest of them to stay put. I understand that I need to use supportedInterfaceOrientations
, but I don't know how or where to use it, and I haven't been able to decipher the Apple Documentation about it. The UITabBarController
is set as the root view controller in AppDelegate
, if that's relevant.
Thanks in advance for the help.
Upvotes: 1
Views: 417
Reputation: 13549
This problem was killing me for a week. I had the exact same situation and only wanted to be able to rotate for one single view also. The way you can get around it in a tabbed app is by registering for orientation notifications. Return NO for shouldAutoRotate in your TabController (and any other superViews) and the VC you want to rotate. Then in viewWillAppear register for the notification:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
And your function that gets called will look like this:
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
case UIDeviceOrientationLandscapeLeft:
if(viewHasAppeared==true){
[self performSegueWithIdentifier:@"firstToLandscape" sender:self];}
break;
case UIDeviceOrientationLandscapeRight:
if(viewHasAppeared==true){
[self performSegueWithIdentifier:@"firstToLandscape" sender:self];}
break;
default:
break;
};
}
-Put a bool inside of ViewDidAppear because you cannot segue until the view actually appears.
Now, if the view your changing to on landscape mode is not a tabbed View Controller, then the best way to handle that is to just allow for AutoRotation in that view and then in willAnimate you just dismiss the VC like so:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation))
{
[self dismissViewControllerAnimated:YES completion:nil];
}
}
If it is a tabbed View then just register for orientationchanges in that view as well. Ensure that you remove the orientationChange notification when you leave the view however. If you don't then you will be seguing to landscape from other viewControllers as well.
And when you leave to go to another tab, you need to have the tabBarController delegate implemented and be sure you remove the observer like so:
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if(![NSStringFromClass([viewController class])isEqualToString:@"FirstViewController"])
{
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}
}
Upvotes: 2
Reputation: 4421
Implement supportedInterfaceOrientations
in your UITabBarController subclass. Here's an example in which the first View Controller won't autorotate out of portrait:
- (NSUInteger)supportedInterfaceOrientations {
if ( self.selectedIndex == 0 )
return UIInterfaceOrientationMaskPortrait ;
else
return UIInterfaceOrientationMaskAll ;
}
However, if you switch to View Controller #2 (index 1), rotate to landscape, and switch back to View Controller #1, you'll see View Controller #1 displaying in landscape. I'm looking for a solution.
Upvotes: 1
Reputation: 3536
An easy way to achieve this is to load your view properly and at the end of your viewDidLoad: method rotate the whole UIView using a transformation
[self.view setTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
Upvotes: -1