17

Tengo una aplicación de 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.iOS 6 UITabBarController orientación compatible con el controlador de UINavigation actual

Me trataron como subclase la tabBarController para devolver el supportedInterfaceOrienations de viewController seleccionada la corriente de navigationController:

- (NSUInteger)supportedInterfaceOrientations{ 

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

Esto me tiene más cerca. 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?

Respuesta

58

Subclase sus UITabBarController primordiales 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 sus UINavigationController primordiales estos métodos:

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

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

luego implementar estos métodos en sus viewControllers que no desea rotar:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

-(BOOL)shouldAutorotate 
{ 
    return NO; 
} 

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait; 
} 

Y para viewControllers que usted desea rotar:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
    { 
     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } 

    -(NSUInteger)supportedInterfaceOrientations 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    -(BOOL)shouldAutorotate 
    { 
     return YES; 
    } 

Su tabBarController debe añadirse que el 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.

+7

Esto casi me funciona. El problema es si ya estoy en el paisaje cuando cambio las pestañas a un retrato a la vista y todavía está en el paisaje. El retrato giratorio lo arregla y no girará de nuevo al paisaje, pero aún necesito que esté en retrato cuando se carga por primera vez. – Ryan

+0

No estoy seguro de qué es exactamente lo que debe hacer para rotarlo, pero apostaría a que lo hace en - (void) viewWillLayoutSubviews. Puede que no esté exactamente en lo cierto con ese nombre de método de memoria. Mis propios puntos de vista, donde utilicé este código, cambian completamente al girar y utilizo ese método para reconfigurarlos de nuevo al modo vertical. También puede probar algo en -viewWillDisappear. Tal vez [self.view setNeedsDisplay]. No estoy en Xcode por el momento, así que estas son solo ideas que exploraría en tu caso. –

+0

¡Agradable! ¡Funciona de maravilla! – Dennso

5

Tuve el problema de que algunos controladores View en la pila 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 hack me ayudó. No estoy seguro si esto se pretende comportamiento o lo

@implementation UINavigationController (iOS6OrientationFix) 

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

@end 
+0

no lo hago Entiendo cómo ese truco te ayudó a tener diferentes comportamientos en diferentes vistas Controlador de un controlador de navegación. Tan pronto como sé, este truco se ejecutará solo una vez, por lo que todos los controladores de vista tendrán el mismo comportamiento de rotación que TopViewController. ¿¿Hing?? –

+1

este código se ejecuta cada vez que el dispositivo cambia de orientación, por lo que se devolverán las orientaciones compatibles para las que uiviewcontroller esté actualmente activo y visible en el momento – Mindaugas

+0

, esto funciona muy bien. Gracias –

3

creo que es mejor algo por el estilo (como método categoría)

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

Esto asegura que se implementa el método. 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.

0

Si planea habilitar o deshabilitar la rotación para todos los controladores de vista no necesita la subclase UINavigationController. usar en su lugar:

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

en su AppDelegate.

Si va a apoyar todas las orientaciones en su aplicación pero diferentes orientaciones sobre PADRE Ver Controladores (UINavigationController pila, por ejemplo) se debe utilizar

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

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

- (BOOL)shouldAutorotate 

y

- (NSUInteger)supportedInterfaceOrientations 

Pero si va a tener diferentes valores de orientación de diferentes ViewControllers niños en la misma pila de navegación (como yo) es necesario comprobar la ViewController actual en la pila de navegación.

He creado el siguiente en mi UINavigationController subclase:

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

Puesto que no puede controlar más de niños ViewControllers la configuración de rotación de controlador de vista presentado que de alguna manera debe interceptar lo controlador de vista se encuentra actualmente en la pila de navegación . Entonces eso es lo que hice :). Espero que ayude !

Cuestiones relacionadas