0

I have an app that has UITabBarController as the base controller with UINavigationController for the two tabs. Both of the tab's main view controllers support both portrait and landscape orientations but the grandchild view needs to be in landscape only.

The problem I'm having is that if you start in portrait before going into the grandchild view, the grandchild's view is being shown in portrait even though ChildViewController's shouldAutorotateToInterfaceOrientation returns YES only for landscape modes. That is, the navigation bar appears towards the top of device as if it's in portrait mode and the new view controller isn't rotated to the forced orientation. It looks like this:

| [Navigation bar] |
|                  |
|  View contents   |
|                  |
|                  |
|                  |

Instead of the correct oriented layout:

|  [Navigation bar]               |
|                                 |
|   View contents, rotated        |

How do I make sure that a grandchild view is shown in the correct orientation? Here's how I'm setting up everything:

// first creating one of two view controllers used for the tabbar

UINavigationController *firstNavController = [[UINavigationController alloc] init];    

ContentOneListController *listController = [[[ContentOneListController alloc] initWithNibName:@"ContentOneView"                                                                                    bundle:nil] autorelease];    
listController.tabBarItem.title = @"One";

firstNavController.viewControllers = [NSArray arrayWithObject:listController];

// view controllers are added to the tabbar controller here (ivar of the class)
tabBarController = [[UITabBarController alloc] init];   
tabBarController.viewControllers = [NSArray arrayWithObjects:
        firstNavController, secondNavController, nil];

[window addSubview:tabBarController.view];
[window makeKeyAndVisible];

// later on, I add a child view controller onto ContentOneListController

NSArray *viewControllers = tabBarController.viewControllers;
NSInteger selectedIndex = [tabBarController selectedIndex]; 
UINavigationController *selectedNavController = [viewControllers objectAtIndex:selectedIndex];  

// ChildViewController only supports landscape orientation
ChildViewController *childController = [[[ChildViewController alloc] initWithNibName:@"ChildView"                                                                                      bundle:nil] autorelease];

[selectedNavController pushViewController:controller animated:NO];

ContentOneListController's shouldAutorotateToInterfaceOrientation returns YES to support both portrait and landscape orientations whereas ChildViewController's shouldAutorotateToInterfaceOrientation returns YES only for landscape orientations:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation 
{
    return (orientation == UIInterfaceOrientationLandscapeLeft ||
            orientation == UIInterfaceOrientationLandscapeRight);
}
Jonas Anderson
  • 1,987
  • 4
  • 24
  • 28

3 Answers3

1

The way to fix this is by adjusting view transform as suggested in this question:

Is there a documented way to set the iPhone orientation?

Community
  • 1
  • 1
Jonas Anderson
  • 1,987
  • 4
  • 24
  • 28
0

I have written an extension that allows to do exactly what you need: https://github.com/piercifani/TabBarBetterRotation

Pierluigi Cifani
  • 224
  • 2
  • 14
0

Subclass UITabBarController and implement shouldAutorotateToInterfaceOrientation for it

Venk
  • 5,949
  • 9
  • 41
  • 52
user210504
  • 1,749
  • 2
  • 17
  • 36
  • Tried that and returned YES for the orientation types I want to support. But the view is still drawn in portrait mode aspect (with the nav bar at top in portrait orientation) instead of the expected landscape orientation. – Jonas Anderson Jan 09 '11 at 20:05