I have a UITabBarController, and each tab handles a different UIViewController that pushes on the stack new controllers as needed. In two of these tabs I need, when a specif
I've been able to use this for a while now (from my app's tab bar controller) without problems:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
That way, in the appropriate VC, we get to do the real check, in this case for a photo gallery view (what else?):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
My gallery view isn't even at the top-of-stack for a given Nav Controller. It still gets called.
Alas, I just discovered that this doesn't work so well when the VC is lurking within the MoreViewController (as opposed to the four main tabs). In that case, my gallery VC never gets called. I think it's because the VC I've been calling all along is really the nav controller from the selected tab, which then propagates things to the appropriate VC, in this case my photo gallery VC. But for the More VC, things don't work so nicely ... aaaand things go rotationally downhill from there. :\
I tried using the modifications by Andreas (see elsewhere in this thread), to no avail. Clues welcome!
I ran into the same issues as you did when working with the UITabBarController. I needed to control which UIViewControllers were allowed to rotate and which were not. My main problem was with the MORE tab. I did not want any of the UIViewControllers included in the MORE tab to rotate.
My solution was to create my own UITabBarController which I called MyTabBarController:
@interface MyTabBarController : UITabBarController <UITabBarDelegate> {
}
Then I implemented the shouldAutorotateToInterfaceOrientation method:
@implementation MyTabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
UIViewController *controller = [self selectedViewController];
if ((controller == [self moreNavigationController]) || ([self selectedIndex] == 4))
{
return interfaceOrientation == UIInterfaceOrientationPortrait;
}
return [controller shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
@end
I needed to discover if the MORE tab was selected. This is a two step process; when the MORE tab is selected initially the API returns a selectedIndex higher than 4 so I needed to compare the selected controller with the moreNavigationController.
If an UIViewController is selected from within the MORE tab then the selectedIndex is finally 4 but the selectedController is not the moreNavigationController anymore but the UIViewController selected.
The if ((controller == [self moreNavigationController]) || ([self selectedIndex] == 4)) takes care of this issue.
Now, when I run my application my UIViewControllers in the MORE tab are not rotated. I hope this will help other developers who are running into the same issues as I did.
Emilio
Here's an extension to UITabBarController that delegates calls to shouldAutorotateToInterfaceOrientation
to the currently selected child controller. Using this extension, you don't need to subclass UITabBarController anymore and you can use shouldAutorotateToInterfaceOrientation
in your controllers like one would expect.
UITabBarController+Autorotate.h:
#import <UIKit/UIKit.h>
@interface UITabBarController (Autorotate)
@end
UITabBarController+Autorotate.m:
#import "UITabBarController+Autorotate.h"
@implementation UITabBarController (Autorotate)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
UIViewController *controller = self.selectedViewController;
if ([controller isKindOfClass:[UINavigationController class]])
controller = [(UINavigationController *)controller visibleViewController];
return [controller shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
@end
This worked for me:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(self.selectedIndex == 0 && [[[self.viewControllers objectAtIndex:0] visibleViewController] isKindOfClass:[MyViewController class]])
return YES;
else
return NO;
}
Thank you, Thank you, Thank you. This has been 2 days in figuring out how to do this. Here is my take on all of your great help when you have a tabBarController with navigationControllers.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
UIViewController *controller = self.selectedViewController;
if ([controller isKindOfClass:[UINavigationController class]])
controller = [(UINavigationController *)controller visibleViewController];
if([controller isKindOfClass:[LOCviewcontroller class]])
return YES;
else
if([controller isKindOfClass:[personWebSiteView class]])
return YES;
else return NO;
}
Any critique of a neophite coder's code is always appreciated...jack
Is it really OK to subclass UITabBarController (as suggested in the accepted answer above)?
I've understood that Apples says something like "you should never ever subclass UITabBarController or UINavigationController" - or have I misunderstood?
Anyway; I found this tutorial where they subclasses a UIViewController in which they put a UITabBarController.