iphone uiviewcontroller orientation landscape

Preguntas frecuentes y soluciones para iPhone Landscape



uiviewcontroller orientation (6)

Ha habido mucha confusión y un conjunto de preguntas correspondientes aquí, sobre el modo en que se pueden implementar las aplicaciones de iPhone con el manejo adecuado para el modo automático / retrato en modo automático. Es especialmente difícil implementar una aplicación de este tipo cuando se desea iniciar en modo horizontal. El efecto observado más común son los diseños encriptados y las áreas de la pantalla donde ya no se reconocen los toques.

Una búsqueda simple de preguntas etiquetadas como iphone y landscape revela estos problemas, que ocurren en ciertos escenarios:

Se han presentado un conjunto de soluciones diferentes, algunas de las cuales incluyen animación completamente personalizada a través de CoreGraphics, mientras que otras se basan en la observación de que el primer controlador de vista cargado desde la punta principal siempre se muestra correctamente.

He pasado una cantidad significativa de tiempo investigando este problema y finalmente encontré una solución que no es solo una solución parcial, sino que debería funcionar en todas estas circunstancias. Es mi intención con esta publicación de CW proporcionar un tipo de preguntas frecuentes para otras personas que tienen problemas con UIViewControllers en modo horizontal.

Por favor, envíe comentarios y ayude a mejorar la calidad de esta publicación incorporando las observaciones relacionadas. Siéntase libre de editar y publicar otras / mejores respuestas si conoce alguna.


¿Qué hay en la documentation ?

En su controlador de vista, anule shouldAutorotateToInterfaceOrientation: para declarar sus orientaciones de interfaz compatibles. Esta propiedad será / debería ser verificada por la infraestructura del controlador cada vez que cambie la orientación del dispositivo.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { return (orientation == UIInterfaceOrientationLandscapeRight); }

Este es el mínimo absoluto que su controlador de vista necesita hacer. Si desea iniciar su aplicación en modo horizontal, debe agregar la siguiente clave a su archivo .plist :

<key>UIInterfaceOrientation</key> <string>UIInterfaceOrientationLandscapeRight</string>

Apple recomienda iniciar las aplicaciones solo en modo horizontal en el modo de derecho horizontal (consulte el HIG en la Guía de experiencia del usuario> Iniciar al instante).

Lo que no está en la documentación:

Un poco de fondo:

Cada vez que intenta cargar un controlador de vista diferente al que está cargado desde la punta principal, su controlador de vista no es interrogado sobre sus orientaciones de interfaz compatibles ni su marco está configurado correctamente. Solo el primer controlador de vista vinculado a la ventana se desplegará correctamente.

Otras personas han sugerido el uso de un "MasterViewController" conectado a la ventana principal a la que otros controladores agregan sus vistas como subvistas en lugar de enlazar directamente a la ventana. Si bien he descubierto que esta solución es una opción viable, no funciona correctamente en el caso de controladores de vista modales agregados a dichas subvistas. También hay un problema si tiene algunas subvistas que deberían poder autorotizar (lo que evitará el controlador maestro).

El uso de API no documentadas para forzar una cierta orientación de la interfaz tampoco es una opción.

La solución:

La mejor solución que he encontrado hasta ahora es una modificación de la solución "MasterViewController". En lugar de utilizar un "MasterViewController" personalizado, se UINavigationController un UINavigationController con barra de navegación oculta y barra de pestañas oculta. Si todas las demás vistas se empujan / saltan desde la pila de navegación de este controlador, las rotaciones automáticas de los controladores en esa pila se administrarán correctamente.

Los controladores modales presentados a través de presentModalViewController:animated: desde cualquiera de los controladores de vista en la pila de navegación de UINavigationController se rotarán y se representarán con el diseño correcto. Si desea que su controlador de vista modal pueda girar a una orientación diferente a la del controlador de vista principal, debe devolver la orientación deseada desde el método shouldAutorotateToInterfaceOrientation del controlador principal mientras se presenta la vista modal. Para restaurar correctamente la orientación de la interfaz cuando se despide el controlador modal, debe asegurarse de que shouldAutorotateToInterfaceOrientation devuelva la orientación deseada para el controlador principal antes de llamar a dismissModalViewController:animated: Puede usar un BOOL privado en su controlador de vista para administrarlo (por ejemplo, BOOL isModalMailControllerActive_ ).

Agregaré un fragmento de código de muestra pronto, es demasiado tarde ahora. Por favor, avíseme si queda algún problema sin resolver o algo no está claro acerca de esta publicación. Siéntase libre de editar y mejorar.


Esto funcionará ...

UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view];


Estoy desarrollando una aplicación para iPad que muestra la vista de galería de desplazamiento vertical de una serie de elementos al iniciar. En el modo paisaje hay 4 elementos a través. En el retrato hay tres. Al girar la orientación del iPad, se supone que debe actualizar la galería para que los elementos se ajusten perfectamente en la pantalla. Luego hago doble toque en un elemento para profundizar en una vista modal de ese elemento. Entonces hago cosas con ese artículo. Finalmente descarto la vista modal.

Durante la actualización o el cambio de orientación, la vista de la galería calcula el número de elementos que se mostrarán según el ancho de la pantalla (o la altura) y la orientación actual de UIViewController.interfaceOrientation.

Estaba teniendo problemas para que esto funcionara correctamente. A veces solo se mostrarían dos elementos en orientación horizontal después de que cerrara el diálogo modal.

Al principio estaba usando los valores de UIViewController.view.frame.size para calcular el número de elementos de la galería. Cuando se descartó la vista modal, este tamaño de cuadro era incorrecto, por ejemplo, el ancho y la altura se habían invertido, aunque la orientación no había cambiado mientras se mostraba el diálogo modal.

Cambié a usar el delegado de la aplicación ([[UIApplication sharedApplication] delegate]] y tomé el window.frame.size para calcular el número de elementos de la galería a mostrar. El window.frame.size se mantiene correcto en los cambios de orientación y los diálogos modales. Los elementos de la galería se muestran correctamente ahora.


Me gustaría agregar a la respuesta de Johannes (usando UINavigationController como MasterViewController).

La desventaja que he encontrado es que los ViewControllers que se insertaron recientemente en la pila de navegación del VC maestro no se ajustan a ningún cambio de orientación anterior. En resumen, los VC que ya están en la pila se giran, los controladores de vista modal presentados desde ellos también se rotan, pero los VC recién agregados no se giran.

He intentado muchos trucos para solucionar esto antes de encontrar uno que funcione. La mayoría solo funciona para pushViewController: con el conjunto animado en SÍ.

Para solucionar el problema por completo, he subclasificado UINagivationController y sobrescribo pushViewController:animated: como sigue:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { // Correctly autoOrient the given view controller [self presentModalViewController:viewController animated:NO]; [self dismissModalViewControllerAnimated:NO]; // Push it as normal (now in its correct orientation) [super pushViewController:viewController animated:animated]; }

La presentación temporal (y bastante invisible) del controlador de vista le permite recibir su actualización de orientación. Luego puede ser empujado en la pila de navegación en su orientación correcta.

Por favor, hágamelo saber si esto funciona para usted. Todas las actualizaciones y mejoras son muy bienvenidas!

Por último, recomiendo el enfoque de Johannes para la gestión de la rotación.

EDITAR: Actualizar en los controladores de vista emergente de la pila

Parece que todos los selectores relacionados con popViewController se vuelven locos cuando se realizan con animated: YES. Específicamente, el controlador de vista está animado en la dirección incorrecta. Puede usar animated: NO y restringir el uso de dichas animaciones a otros UINavigationControllers más abajo en su jerarquía (es decir, las que empuja en la pila del controlador de navegación raíz).

Cualquier aporte es muy apreciado.


Para la segunda viñeta, si desea utilizar pushViewController para pasar de la vista solo vertical a solo horizontal, un simple truco que encontré es colocar el siguiente código en viewDidLoad de su controlador empujado:

UIViewController *viewController = [[UIViewController alloc] init]; [self presentModalViewController:viewController animated:NO]; [self dismissModalViewControllerAnimated:NO]; [viewController release];


Tenía un requisito interesante para la aplicación de iOS:

vista principal El controlador debe ser solo horizontal, pero todos los demás (que pueden ser empujados desde la principal) pueden ser horizontal y vertical.

El problema está presente: cuando presiono hacia un nuevo viewController, que luego se gira para retratar, y la ventana emergente emergente principal ya no es horizontal. Además - la aplicación de apertura, no está en el paisaje.

Con el fin de mantener el panorama del controlador de vista principal, sin importar de qué orientación se abriera / empujó, 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];

¡Ojalá ayude a alguien!

PSTested en sdk 3.2.5 ios 5.0.1.

PS Gracias por toda la información en este FAQ!