IOS 6 UITabBarController supports orientation with the current UINavigation controller

I have an iPhone app that I upgrade to iOS 6, which has rotation issues. I have a UITabBarController with 16 UINavigationCotrollers . Most subzones can work in portrait or landscape orientation, but some of them are only portrait. With iOS 6, things spin when they shouldn't.

I tried to subclass tabBarController to return the supportedInterfaceOrienations currently selected ControlController navigationController:

 - (NSUInteger)supportedInterfaceOrientations{ UINavigationController *navController = (UINavigationController *)self.selectedViewController; return [navController.visibleViewController supportedInterfaceOrientations]; } 

It brought me closer. The view controller will not rotate out of position when it is visible, but if I am in landscape orientation and switch tabs, the new tab will be in the landscape, even if it is not supported.

Ideally, the application will only be in the supported orientation of the current visible controller. Any ideas?

+17
rotation ios6 uitabbarcontroller orientation uinavigationcontroller
Sep 19 '12 at 23:57
source share
4 answers

A subclass of your UITabBarController overrides these methods:

 -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // You do not need this method if you are not supporting earlier iOS Versions return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; } -(NSUInteger)supportedInterfaceOrientations { return [self.selectedViewController supportedInterfaceOrientations]; } -(BOOL)shouldAutorotate { return YES; } 

A subclass of your UINavigationController overrides these methods:

 -(NSUInteger)supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; } -(BOOL)shouldAutorotate { return YES; } 

Then implement these methods in your viewControllers that you do not want to rotate:

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } -(BOOL)shouldAutorotate { return NO; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 

And to view the controllers you want to rotate:

  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; } -(BOOL)shouldAutorotate { return YES; } 

Your tabbarController should be added as a RootviewController application window. If you plan to support the default orientation, all but the upsidedown, by default for the iPhone, then you do not need to do anything. If you want to support inverted or if you do not want to support a different orientation, you need to set the appropriate values ​​in the application delegate and / or info.plist.

+58
Sep 20
source share

I had a problem that some View controllers in the navigation stack support all orientations, some only portraits, but the UINavigationController returns all orientations supported by applications, this little hack helped me. I'm not sure if this is the intended behavior or what

 @implementation UINavigationController (iOS6OrientationFix) -(NSUInteger) supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; } @end 
+5
Sep 20 '12 at 11:45
source share

I think something like this is better (as a category method)

 -(NSUInteger) supportedInterfaceOrientations { if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)]) { return [self.topViewController supportedInterfaceOrientations]; } return UIInterfaceOrientationMaskPortrait; } 

this ensures that the method is implemented. If you do not perform this check and the method is not implemented (for example, in iOS5 env), the application should work!

+3
02 Oct '12 at 12:15
source share

If you plan to enable or disable rotation for all view controllers, you do not need to subclass UINavigationController . Use instead:

  -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

in AppDelegate .

If you plan to support all orientations in your application, but different orientations on PARENT View controllers (for example, UINavigationController ), you should use

  -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

from AppDelegate in combination with the following methods in your PARENT view controller.

  - (BOOL)shouldAutorotate 

and

 - (NSUInteger)supportedInterfaceOrientations 

But if you plan to have different orientation settings in different CHILDREN ViewControllers in the same navigation stack (like me), you need to check the current ViewController in the navigation stack.

In my subclass of UINavigationController I created the following:

  - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { int interfaceOrientation = 0; if (self.viewControllers.count > 0) { DLog(@"%@", self.viewControllers); for (id viewController in self.viewControllers) { if ([viewController isKindOfClass:([InitialUseViewController class])]) { interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; } else if ([viewController isKindOfClass:([MainViewController class])]) { interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; } else { interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown; } } } return interfaceOrientation; } 

Since you can no longer control the rotation parameters of the presented view controller using the ViewControllers, you must somehow intercept which view controller is currently in the navigation stack. So this is what I did :). Hope this helps!

0
Jan 20 '13 at 0:51
source share



All Articles