2012-09-13 68 views
36

Tengo este problema con iOS 6 SDK: tengo algunas vistas que deberían poder rotar (por ejemplo, una videoview), y otras que no. Ahora entiendo que tengo que verificar todas las orientaciones en Info.plist de la aplicación y luego ordenar en cada ViewController, lo que debería suceder. ¡Pero no funciona! La aplicación siempre gira a las orientaciones, que se dan en Info.plist.iOS 6 rotaciones: supportedInterfaceOrientations no funciona?

Info.plist:

<key>UISupportedInterfaceOrientations</key> 
    <array> 
     <string>UIInterfaceOrientationPortrait</string> 
     <string>UIInterfaceOrientationLandscapeLeft</string> 
     <string>UIInterfaceOrientationLandscapeRight</string> 
    </array> 

cualquier ViewController que shouldn't ser permite que gire:

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

- (NSUInteger)supportedInterfaceOrientations{ 
return UIInterfaceOrientationMaskPortrait; 
} 

Observación: App gira para paisaje y la orientación vertical. ¿Alguna idea de por qué o qué estoy haciendo mal?

Saludos, Marc

Editar: Mis últimos resultados también indican que, si usted quiere tener la rotación en algún momento de su aplicación, tiene para activar los cuatro sentidos de giro en la configuración del proyecto o Información .plist. Una alternativa a esto es anular

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

en su AppDelegate, que anula el Info.plist. Ya no es posible configurar Portrait en su Info.plist y luego tener rotación en ViewController anulando shouldAutorotateToInterfaceOrientation o supportedInterfaceOrientations.

+0

Esto está bajo NDA, publíquelo en los foros de apple dev y le puedo ayudar. –

+0

¿Es mejor así? Supongo que ahora a nadie le importaría dañar a NDA ... – stk

+0

sigue siendo un NDA, también supongo que este es un problema común y ha sido totalmente respondido en los foros de desarrolladores ya – wattson12

Respuesta

31

Si su ViewController es hijo de un UINavigationController o UITabBarController, entonces es el padre el que es su problema. Puede que sea necesario que la subclase controlador de vista de los padres, simplemente reemplazando los métodos InterfaceOrientation como se ha mostrado en su pregunta

EDIT:

Ejemplo para el retrato solamente tabBarController

  @interface MyTabBarController : UITabBarController 
      { 
      } 
      @end 

      @implementation MyTabBarController 

      // put your shouldAutorotateToInterfaceOrientation and other overrides here   
      - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
       return (interfaceOrientation == UIInterfaceOrientationPortrait); 
      } 

      - (NSUInteger)supportedInterfaceOrientations{ 
       return UIInterfaceOrientationMaskPortrait; 
      } 

     @end 
+4

y no debes olvidar el método de supportInterfaceOrientations, porque en iOS6, shouldAutorotate ... ya no se usa! – stk

-2

Como opción alternativa, en caso de que desee conservar la funcionalidad de rotación anterior a iOS6 en su aplicación:

Aquí hay un fragmento útil de código en github que encapsula las llamadas de método para iOS6 para que la rotación funcione como lo hizo en iOS4/iOS4. Esto realmente me ayudó, ya que estoy apoyando una aplicación heredada que realmente micro-gestiona sus rotaciones. Hubiera sido mucho trabajo implementar los cambios necesarios para iOS6. Felicitaciones al usuario que lo publicó.

https://gist.github.com/3725118

+1

Esta es una muy, muy mala idea. Sólo digo'. – steipete

27

Agregando a la respuesta de CSmith anteriormente, el código siguiente en una subclase UINavigationController permite la delegación al controlador vista superior de la forma que yo esperaba que esto funcione en el primer lugar:

- (BOOL)shouldAutorotate; 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    if ([[self topViewController] respondsToSelector:@selector(supportedInterfaceOrientations)]) 
     return [[self topViewController] supportedInterfaceOrientations]; 
    else 
     return [super supportedInterfaceOrientations]; 
} 
+5

¡Esto funciona perfectamente! y por qué esto no lo hace Apple IOS SDK? :( – flypig

+5

@flypig, solía serlo. El iOS SDK de Apple se comportó exactamente como este anteriormente. Lo cambiaron al nuevo sistema sin ningún motivo aparente con iOS 6. –

8

Aquí hay otra alternativa al enfoque de CSmith.

Si desea replicar el 6 de comportamiento pre-IOS donde todos los puntos de vista en la barra de pila de desplazamiento/pestaña tienen que ponerse de acuerdo sobre un conjunto permitido de orientaciones, ponga esto en su subclase de UITabBarController o UINavigationController:

- (NSUInteger)supportedInterfaceOrientations 
{ 
    NSUInteger orientations = [super supportedInterfaceOrientations]; 

    for (UIViewController *controller in self.viewControllers) 
     orientations = orientations & [controller supportedInterfaceOrientations]; 

    return orientations; 
} 
2

intenta agregar esta categoría:

@interface UINavigationController(InterfaceOrientation) 

@end 

@implementation UINavigationController(InterfaceOrientation) 

- (NSUInteger) supportedInterfaceOrientations { 
    if (self.viewControllers.count > 0) 
     return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations]; 
    else 
     return UIInterfaceOrientationMaskAll; 
} 

@end 
+0

Funciona muy bien, ¡cualquier subclasificación! ¡Gracias! Pero prefiero usar último controlador de vista en la matriz, que actualmente se muestra. – HotJard

-1
respuesta de

@Shimanski Artem es buena, pero creo que el uso de la más alta controlador (actualmente visible) está mejor solución:

@interface UINavigationController(InterfaceOrientation) 

@end 

@implementation UINavigationController(InterfaceOrientation) 

- (NSUInteger) supportedInterfaceOrientations { 
    if (self.viewControllers.count > 0){ 
     return [[self.viewControllers objectAtIndex:[self.viewControllers count] - 1] supportedInterfaceOrientations]; 
    } 
    return UIInterfaceOrientationMaskAll; 
} 

@end 
0

Además de @CSmith y @EvanSchoenberg.

Si tiene algunas vistas que giran, y algunas que no, debe crear una instancia personalizada de UITabBarController, y aun así dejar que cada UIViewController decida.

- (BOOL)shouldAutorotate; 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    UIViewController * top; 
    UIViewController * tab = self.selectedViewController; 
    if([tab isKindOfClass: 
     ([UINavigationController class])]) { 
     top = [((UINavigationController *)tab) 
       topViewController]; 
    } 

    if ([top respondsToSelector:@selector(supportedInterfaceOrientations)]) 
     return [top supportedInterfaceOrientations]; 
    else 
     return [super supportedInterfaceOrientations]; 
} 
0

Para las personas que utilizan UINavigationController y Swift, puede agregar esta extensión para su proyecto. Después de eso, los controladores de navegación delegan el control a su controlador hijo.

extension UINavigationController { 
    override public func supportedInterfaceOrientations() 
    -> UIInterfaceOrientationMask { 
     if let ctrl = topViewController { 
      return ctrl.supportedInterfaceOrientations() 
     } 
     return super.supportedInterfaceOrientations() 
    } 

    override public func shouldAutorotate() -> Bool { 
     if let ctrl = topViewController { 
      return ctrl.shouldAutorotate() 
     } 
     return super.shouldAutorotate() 
    } 
} 
Cuestiones relacionadas