iOS: deshabilitar la autorrotación para una subvista

Tengo una jerarquía de vista anidada para una aplicación de iPad que admite cambios de orientación. Se parece a lo siguiente.

UIViewController UIView - UIView - UIImageView (disable rotation) - UIImageView - UIView (disable rotation) - UIView - UIView ... 

Me gustaría bloquear la orientación de algunas de mis subvistas, mientras que otras permiten rotar y cambiar el tamaño automáticamente. No puedo entender cómo lograr esto.

Un enfoque parece estar rotando manualmente las subvistas dentro de willAnimateRotationToInterfaceOrientation: Eso no es particularmente atractivo dado que el SDK está ejecutando una rotación que yo simplemente estaría deshaciendo.

¿Hay alguna manera de simplemente deshabilitar los cambios de orientación para las subvistas o algún otro método para reestructurar mi jerarquía?

La autorrotación se maneja mediante el UIViewController de una vista ( shouldAutorotateToInterfaceOrientation: , por lo que un enfoque es organizar su jerarquía de modo que las vistas giratorias sean administradas por un controlador de vistas y las vistas no rotativas por otro controlador de vistas. Ambas vistas de raíz de este UIViewController necesitan agregarse a la ventana / supervista.

La sutileza aquí es que si tiene dos vistas de controlador de vista en el mismo nivel (es decir, agregadas a través de addSubview: , solo el primer controlador de vista (por lo general, el controlador rootViewController la ventana) recibirá el mensaje shouldAutorotateToInterfaceOrientation:

Usé este enfoque yo mismo para lograr una barra de herramientas que gira, mientras que la vista principal no.

Preguntas y respuestas técnicas de Apple QA1688 (“¿Por qué mi UIViewController no girará con el dispositivo?”) Habla un poco sobre este tema.

Actualización para iOS 6:

Autorotación ahora usa los UIViewController shouldAutorotate y supportedInterfaceOrientations shouldAutorotate . shouldAutorotate devuelve YES de manera predeterminada, pero recuerde que un controlador de vista que no sea el controlador rootViewController cuya vista es una subvista directa de la ventana NO recibirá devoluciones de llamadas de todos modos.


Código de muestra para iOS 6:

Cree un nuevo proyecto usando la plantilla “Aplicación de vista única” y asegúrese de que esté marcado “Usar guiones gráficos”. Usaremos la clase ViewController proporcionada como controlador de vista giratoria (¡cambie el nombre si lo desea!) Y cree una segunda subclase NonRotatingViewController llamada NonRotatingViewController . Aunque este controlador de vista nunca recibirá las devoluciones de llamada de rotación, para completar y aclarar agregue el siguiente código en NonRotatingViewController.m :

 - (BOOL)shouldAutorotate { return NO; } 

En el archivo MainStoryboard , arrastre un nuevo objeto controlador de vista y establezca su clase en NonRotatingViewController , y establezca su ID Storyboard en “NonRotatingVC”. Mientras está allí, cambie el color de fondo de la vista del controlador de vista giratoria para borrar (la vista no giratoria se agregará debajo de esta) y agregue una etiqueta a cada vista. En AppDelegate.m , agregue el siguiente código:

 #import "NonRotatingViewController.h" // ... // ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; NonRotatingViewController *nonRotatingVC = [mainStoryboard instantiateViewControllerWithIdentifier:@"NonRotatingVC"]; [self.window addSubview:nonRotatingVC.view]; return YES; } 

Esto es solo crear instancias de un controlador de vista no giratorio y agregar su vista directamente a la ventana (Nota: en este punto, el guión gráfico ya ha configurado el controlador de vista de la ventana).

Ejecute el proyecto. Gire el dispositivo y maravíllese al ver que una etiqueta gira mientras que la otra permanece quieta.


Código de muestra pre iOS 6:

Hice esto en un nuevo proyecto: una nueva aplicación basada en la vista funcionará perfectamente. Agregue dos nuevos controladores de vista: RotatingViewController y NonRotatingViewController . Dentro de cada una de sus puntas, acabo de agregar una etiqueta para describir si la vista debería rotar o no. Agregue el siguiente código:

RotatingViewController.m

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

NonRotatingViewController.m

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if (interfaceOrientation == UIInterfaceOrientationPortrait) { // Or whatever orientation it will be presented in. return YES; } return NO; } 

AppDelegate.m

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { RotatingViewController *rotating = [[RotatingViewController alloc] initWithNibName:@"RotatingViewController" bundle:nil]; self.rotatingViewController = rotating; [rotating release]; NonRotatingViewController *nonRotating = [[NonRotatingViewController alloc] initWithNibName:@"NonRotatingViewController" bundle:nil]; self.nonRotatingViewController = nonRotating; [nonRotating release]; [self.window addSubview:self.rotatingViewController.view]; [self.window insertSubview:self.nonRotatingViewController.view belowSubview:self.rotatingViewController.view]; [self.window makeKeyAndVisible]; return YES; } 

Espero que esto ayude.

    Intereting Posts