iOS 6 UITabBarController apoyó la orientación con el controlador UINavigation actual

Tengo una aplicación para iPhone. Estoy actualizando a iOS 6 que tiene problemas de rotación. Tengo un UITabBarController con 16 UINavigationCotrollers . La mayoría de las subvistas pueden funcionar en vertical u horizontal, pero algunas solo son retratos. Con iOS 6 las cosas están girando cuando no deberían.

Intenté subclasificar el tabBarController para devolver las OrganizationInterfaceOrienations supportedInterfaceOrienations del viewController seleccionado de navigationController:

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

Esto me acercó más. El controlador de vista no girará fuera de posición cuando esté visible, pero si estoy en horizontal y cambie de pestaña, la nueva pestaña estará en horizontal incluso si no es compatible.

Idealmente, la aplicación solo estará en la orientación compatible del controlador de vista visible actual. ¿Algunas ideas?

Subclase su UITabBarController anulando estos métodos:

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

Subclase su UINavigationController anulando estos métodos:

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

Luego implemente estos métodos en su viewControllers que no desea rotar:

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

Y para viewControllers que desea rotar:

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

Su tabbarController se debe agregar como RootviewController de la ventana de la aplicación. Si planea admitir las orientaciones predeterminadas, todo lo contrario al revés es el predeterminado para iPhone, entonces no necesita hacer nada más. Si desea apoyar al revés o si no desea admitir otra de las orientaciones, debe establecer los valores adecuados en delegado de la aplicación y / o info.plist.

Tuve problema de que algunos controladores de View en la stack de navegación admiten todas las orientaciones, algunos solo retrato, pero UINavigationController devolvía todas las orientaciones compatibles con la aplicación, este pequeño truco me ayudó. No estoy seguro si este es el comportamiento previsto o qué

 @implementation UINavigationController (iOS6OrientationFix) -(NSUInteger) supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; } @end 

Creo que es mejor algo así (como método de categoría)

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

esto asegura que el método se implemente. Si no está haciendo esta comprobación y el método no está implementado (como en el env de iOS5) la aplicación debería bloquearse.

Si planea habilitar o deshabilitar la rotación para todos los controladores de vista, no necesita subclasificar UINavigationController . En su lugar use:

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

en su AppDelegate .

Si planea admitir todas las orientaciones en su aplicación pero diferentes orientaciones en los Controladores de Vista de PADRES (por ejemplo, la stack UINavigationController ) debe usar

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

de AppDelegate en combinación con los siguientes métodos en su Controlador de Vista de PADRES.

  - (BOOL)shouldAutorotate 

y

 - (NSUInteger)supportedInterfaceOrientations 

Pero si planea tener diferentes configuraciones de orientación en diferentes ViewControllers de CHILDREN en la misma stack de navegación (como yo), debe verificar el ViewController actual en la stack de navegación.

UINavigationController siguiente en mi subclase UINavigationController :

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

Como ya no puede controlar desde los controles ViewControllers de los niños, la configuración de rotación del controlador de vista presentado debe interceptar de algún modo qué controlador de vista se encuentra actualmente en la stack de navegación. Entonces eso es lo que hice :). Espero que ayude !