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]];
}
}