user798719
user798719

Reputation: 9869

Autorotating only some of the tabs inside a UITabBar? (ios 5)

I have a UITabBar with 5 tabs. I only wish to enable autorotation for a UIViewController that gets pushed onto the stack deep inside tab #3. So to be clear: tap UITabBar item 3, and you get tabbar item #3's root UIView, which should not autorotate. Tap and get another UIViewController pushed onto the stack (via a UINavigationController). Tap again, and get another UIViewController pushed onto the stack. Only here should this UIView autorotate.

The other 4 tabs should not rotate at all--not the root view of the tabs, nor any of the child views of the tabs.

Can someone tell me what approach I should use? I read that every single tab needs to respond "YES" to willAutorotateToInterfaceOrientation.

Upvotes: 1

Views: 198

Answers (1)

Wienke
Wienke

Reputation: 3733

In each view's shouldAutorotate..., you could call a method in the root view controller that checks what is currently being displayed. If the deep-level view for tab 3 is on display, it will return YES, otherwise NO, and the views will, in turn, return the same.


Edit -- more detail per user798719's request:

Your root view controller knows which view is on display. You add a method to the root view controller - (BOOL) isDeepLevelTab3Displayed;. The method checks whether the deep-level view for tab 3 is on display and, if so, returns YES, otherwise returns NO.

Each sub view controller’s shouldAutorotate… method will get a ref to the root controller so that it can call isDeepLevelTab3Displayed.

If you’re using a navigation-style controller, you can get the ref like this (self is the sub controller):

NSArray *arrayOfControllers = [self viewControllers];
UIViewController *rootController = [arrayOfControllers objectAtIndex:0]; // per UIViewController class ref, root controller is at index 0

Or you could get anything in your project like this:

YourProjectAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
UIViewController *rootController = appDelegate.rootController; // or appDelegate.intermediateClass1.intermClass2.rootController — however you set up your project

So every sub controller would do this:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {  
    UIViewController *rootController = [[self viewControllers] objectAtIndex:0];
    return [rootController isDeepLevelTab3Displayed];
}

Therefore, every subcontroller would return YES when autorotation should happen, fulfilling the requirement you mention at the end of your question.

However, if all your subcontrollers are instances of UINavigationController, you could determine which view is currently on display directly, by calling visibleViewController. Then you just need a way of checking its identity.

You could check the controller’s nibName or title, for example, against a constant, or add an integer property intControllerIdentity to all your controllers and set them in the controller’s initWithNibName… The integer-property scheme might be best, because it won’t be affected should you later change the nibName or title.

You’d add constants to some class whose h file is imported by all the controllers (or, if all the controllers are instances of the same class, put these constants in that class’s h file):

#define kFooController 1
#define kBarController 2
#define kRotatableController 3

And you’d set it like this:

self.intControllerIdentity = kRotatableController;

And check it like this:

if (self.intControllerIdentity == kRotatableController)

Hope that helps. But evaluate this added detail with a critical eye; I have worked with autorotation but not yet with navigation controllers.

Upvotes: 2

Related Questions