2012-03-22 12 views
19

Mi aplicación es principalmente retrato, sin embargo, hay una vista que REQUIERE una orientación horizontal.UINavigationController Force Rotate

Mis vistas se encuentran dentro de un UINavigationController, que (aparentemente) es la causa de este problema.

Todos UIViewControllers, excepto uno, tienen esta:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

El UIViewController que requiere paisaje tiene esta:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight); 
} 

Ahora, lo que sucede es cuando el usuario llega al paisaje UIViewController, se muestra en retrato. El usuario puede rotar su teléfono y se muestra en el paisaje como yo quiero (bloqueo a horizontal). El usuario luego avanza hacia un UIViewController vertical y sucede lo mismo: comienza en el paisaje, luego gira su teléfono y se vuelve a retratar (y se bloquea a vertical).

Parece que se permite el bloqueo de orientación entre UIViewControllers, sin embargo, la auto rotación/cambio de la orientación de forma programada está bloqueada de alguna manera.

¿Cómo obligo a que el teléfono se actualice con la orientación correcta?

Existe una solución temporal: puedo detectar la orientación del dispositivo y mostrar un mensaje pidiéndoles que giren el dispositivo si no es correcto, aunque esto no es óptimo.

Respuesta

27

¡Tenía el mismo requisito para una de mis aplicaciones!

¡afortunadamente encontré una solución!

Con el fin de mantener el paisaje principal viewcontroller, no importa de qué orientación se metió/empujados, hice lo siguiente: (en viewWillAppear :)

//set statusbar to the desired rotation position 
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO]; 

//present/dismiss viewcontroller in order to activate rotating. 
UIViewController *mVC = [[[UIViewController alloc] init] autorelease]; 
[self presentModalViewController:mVC animated:NO]; 
[self dismissModalViewControllerAnimated:NO]; 

PSTested el SDK 3.2.5 ios 5.0.1.

P.S. En iOS 8 respuesta anterior da como resultado algo de parpadeo de la pantalla y también - no es estable (en algunos casos no funciona para mí.) Por lo tanto, para mis necesidades, me cambió el código para: (ARC)

//set statusbar to the desired rotation position 
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO]; 

[self.navigationController presentViewController:[UIViewController new] animated:NO completion:^{ 
    dispatch_after(0, dispatch_get_main_queue(), ^{ 
     [self.navigationController dismissViewControllerAnimated:NO completion:nil]; 
    }); 
}]; 

//I added this code in viewDidDissapear on viewController class, which will be popped back. 

¡Espero que ayude!

+0

Funciona en iOS6beta1. ¡Gracias! – k06a

+0

Para mí, con 'UINavigationController', este enfoque falla porque aunque la barra de estado gira, la interfaz aún permanece. Entonces el usuario debe rotarlo una vez más para configurar la interfaz. –

+0

Sí, yo mismo tuve una situación en la que este truco no funcionó después de todo. Eso significa que la funcionalidad de su aplicación (conversión de tamaño del elemento o integración de vista/subvista demasiado profunda o probablemente algo más) no permite que esta característica funcione. lo siento. En casos simples, ayuda. –

20

Esto podría ayudar. Puede llamar al siguiente método al aparecer, según corresponda. p.ej. en -viewWillAppear:animated

attemptRotationToDeviceOrientation intenta girar todas las ventanas a la orientación del dispositivo.

+ (void)attemptRotationToDeviceOrientation 

Discusión

Algunos controladores de vista pueden desear utilizar condiciones específicas de la aplicación a determinar el valor de retorno de la aplicación de la shouldAutorotateToInterfaceOrientation: método. Si su controlador de vista hace esto, cuando esas condiciones cambian, su aplicación debe llamar al este método de clase. El sistema inmediatamente intenta rotar a la nueva orientación. Se produce una rotación siempre que cada controlador de vista relevante devuelva SÍ en su implementación del método shouldAutorotateToInterfaceOrientation :.

disponibilidad

Disponible en iOS 5.0 y posterior. http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html

+1

wow 1 buen consejo (y otra chuchería en OS5). este problema me ha dado muchas horas de dolor de cabeza. – danh

+0

Hay todo tipo de funciones para establecer la configuración de autorrotación allí, pero no parecen ser llamadas constantemente. Puse - (BOOL) shouldAutorotate { return NO; } Pero esto nunca se llamó. – shim

+0

Impresionante, ¡tan bueno! ¡Esto me ha eludido por años! Muchas gracias – joehanna

4

Uso esto,

[[UIDevice currentDevice]performSelector:@selector(setOrientation:) withObject:(__bridge id)((void *)UIInterfaceOrientationLandscapeRight)]; 
+0

funciona pero siento que podría romperse en el futuro ya que probablemente no está documentado. – MobileMon

+0

No, es una orientación nativa de la manzana. Lo he usado y obtuve la aprobación de apple para 2 de mis aplicaciones. – Thangavel

+0

Mejor forma de escribirlo: '[[UIDevice currentDevice] setValue: @ (UIDeviceOrientationLandscapeLeft) forKey: @" orientation "]' – meisel