Autorotate en iOS 6 tiene un comportamiento extraño

Tengo la aplicación UITabBarController que reproduce video y muestra otra información en otras tabs de UITabBar . En iOS 6, los métodos de rotación de UIView han quedado en desuso, y ahora tengo que utilizar los métodos shouldAutoRotate y supportedInterfaceOrientations . Para reproducir videos utilizo MPMoviePlayerViewController .

¿Cómo rotar solo esta vista de jugador? Solo puedo rotar la aplicación completa, pero no quiero hacer esto. MPMoviePlayerViewController pero no gira como en iOS 5 y anteriores.

En la configuración plist configuré solo 1 orientación de la interfaz de retrato. Si configuro otro, se rotará la aplicación completa.

De las notas de la versión del SDK iOS 6 de Apple:

La autorotación está cambiando en iOS 6. En iOS 6, el método shouldAutorotateToInterfaceOrientation: de UIViewController está en desuso. En su lugar, debe usar la estructura de interfaz soportada para la ventana: y debeautorizar los métodos.

Se está transfiriendo más responsabilidad a la aplicación y a la aplicación delegada. Ahora, los contenedores iOS (como UINavigationController) no consultan a sus hijos para determinar si deben autorrotar. De forma predeterminada, las orientaciones de interfaz admitidas por una aplicación y un controlador de vista están configuradas en UIInterfaceOrientationMaskAll para el idioma del iPad y UIInterfaceOrientationMaskAllButUpsideDown para el idioma del iPhone.

Las orientaciones de interfaz admitidas por un controlador de vista pueden cambiar con el tiempo; incluso las orientaciones de interfaz compatibles de una aplicación pueden cambiar con el tiempo. El sistema pregunta al controlador de vista de pantalla completa más alto (generalmente el controlador de vista raíz) por sus orientaciones de interfaz compatibles cada vez que el dispositivo gira o cada vez que se presenta un controlador de vista con el estilo de presentación modal de pantalla completa. Además, las orientaciones admitidas se recuperan solo si este controlador de vista devuelve SÍ de su método shouldAutorotate. El sistema intersecta las orientaciones admitidas del controlador de vista con las orientaciones admitidas de la aplicación (según lo determinado por el archivo Info.plist o la aplicación del delegado de la aplicación: supportedInterfaceOrientationsForWindow: method) para determinar si se debe rotar.

El sistema determina si se admite una orientación intersectando el valor devuelto por el método supportedInterfaceOrientationsForWindow de la aplicación con el valor devuelto por el método supportedInterfaceOrientations del controlador de pantalla completa superior. El método setStatusBarOrientation: animado: no está obsoleto. Ahora solo funciona si el método supportedInterfaceOrientations del controlador de vista de pantalla completa más alta devuelve 0. Esto hace que el llamador sea responsable de garantizar que la orientación de la barra de estado sea coherente.

Para compatibilidad, los controladores de vista que todavía implementan el método shouldAutorotateToInterfaceOrientation: no obtienen los nuevos comportamientos de autorrotación. (En otras palabras, no recurren al uso de la aplicación, el delegado de la aplicación o el archivo Info.plist para determinar las orientaciones admitidas). En su lugar, el método shouldAutorotateToInterfaceOrientation se usa para sintetizar la información que sería devuelta por el método supportedInterfaceOrientations .

Si quieres que toda tu aplicación gire, deberías configurar tu Info.plist para que sea compatible con todas las orientaciones. Ahora bien, si desea que una vista específica sea solo retrato, tendrá que hacer una especie de subclase y anular los métodos de autorrotación para devolver solo el retrato. Tengo un ejemplo aquí:

https://stackoverflow.com/a/12522119/1575017

Ough! ¡Pasó medio día y se resolvió el problema! Él el.

Como dice la documentación anterior, ¡esto es realmente así! Los puntos principales son:

Se está transfiriendo más responsabilidad a la aplicación y a la aplicación delegada . Ahora, los contenedores iOS (como UINavigationController) no consultan a sus hijos para determinar si deben autorrotar. De forma predeterminada, las orientaciones de interfaz admitidas por una aplicación y un controlador de vista están configuradas en UIInterfaceOrientationMaskAll para el idioma del iPad y UIInterfaceOrientationMaskAllButUpsideDown para el idioma del iPhone.

Entonces, cada vez que algo con el controlador raíz cambia, el sistema pregunta a la aplicación delegada “Entonces, ¿qué somos? ¿Rotar o no?”

Si está “girando”:

las orientaciones admitidas se recuperan solo si este controlador de vista devuelve SÍ desde su método shouldAutorotate

entonces el sistema le pregunta a nuestro delegado de aplicaciones

 - (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return ...; } 

Eso es realmente bastante simple.

Cómo decidir cuándo debemos permitir Portrait o Landscape, etc., depende de usted. Las pruebas para el controlador raíz no funcionaron para mí debido a algunos puntos, pero esto funciona:

 - (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return self.fullScreenVideoIsPlaying ? UIInterfaceOrientationMaskAllButUpsideDown : UIInterfaceOrientationMaskPortrait; } 

La propiedad “fullScreenVideoIsPlaying” la configuro manualmente cada vez que lo necesito.

La única otra cosa importante a tener cuidado es la enumeración. Como dice en los documentos … (lea cuidadosamente arriba de lo del iPad / iPhone). Entonces, puedes jugar con ellos cuando lo necesites.

Otra cosa pequeña fue algún comportamiento con errores después de cerrar el controlador del reproductor. Hubo un momento en que no cambió la orientación, pero eso sucedió una vez y de una manera extraña, y solo en el simulador (solo iOS 6, por supuesto). Así que incluso no pude reactjsr, ya que sucedió inesperadamente y después de hacer clic rápidamente en algunos otros elementos de mi aplicación, giró a la orientación normal. Por lo tanto, no estoy seguro, puede haber algún retraso en el trabajo del simulador o algo así (o, realmente, un error :)).

¡Buena suerte!

Tuve el mismo problema con mi aplicación.

Cómo funciona la rotación en iOS 6 es eso.

=> cuando esté usando UINavigationCOntroller el método en AppDelegate

 - (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return } 

decide si rotar o no.

=> cuando la vista se presenta en el estilo de presentación Modal el método

 - (BOOL)shouldAutorotate 

que está dentro de viewController para esa vista activa el método en la aplicaciónDelegate. Y como primer caso, appDelegate decide rotar o no.

Mi solución::

Lo que hice para la presentación modal fue eso. Creado una bandera en delegado de aplicación.

cuando alguna vez la bandera es SÍ, gira a Paisaje y de lo contrario es solo Retrato.

 - (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window { if(self.shouldRotate ) //shouldRotate is my flag { self.shouldRotate = NO; return (UIInterfaceOrientationMaskAll); } return (UIInterfaceOrientationMaskPortrait); } 

Y para alternar entre rotaciones

 - (BOOL)shouldAutorotate { YourAppDelegate *mainDelegate = (YourAppDelegate*)[[UIApplication sharedApplication]delegate]; mainDelegate.shouldRotate = YES; return YES; } 

Nota : Esto funciona solo para ver que están presentados de forma moderada. Usar Flag, no es una buena práctica de encoding.

También puede subescribir UITabBarController para que pregunte a sus hijos sobre el shouldAutorotate y supportedInterfaceOrientation de la siguiente manera:

 @implementation MyTabBarController -(BOOL)shouldAutorotate { return [self.selectedViewController shouldAutorotate]; } -(NSUInteger)supportedInterfaceOrientations { return [self.selectedViewController supportedInterfaceOrientations]; } @end 

¡Entonces solo usa su contenedor personalizado en lugar del estándar y funciona! acaba de probar.

Desafortunadamente, tendrá que activar todas las orientaciones en su plist y utilizar las orientaciones de interfaz compatibles en todos los controles de vista que no desee rotar. (En tu caso, todo menos el reproductor de video).

Prueba esto,

Si TabBarController es RootViewController para la ventana, entonces Create Custom Class que hereda TabBarController dice CustomTabBarController.h

Método Agregar Abajo en CustomTabBarController.h

 -(NSUInteger)supportedInterfaceOrientations // Must return Orientation Mask 

Finalmente, llame abajo en AppDelegate.m

 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { if( [self.window.rootViewController supportedInterfaceOrientations]!=0) { return [self.window.rootViewController supportedInterfaceOrientations]; } return UIInterfaceOrientationMaskAll; } 

Descubrí que la manera más fácil de configurar esto es usar los botones de “orientaciones de interfaz admitidas” que puede ver si mira los Objetivos … Pestaña Resumen (en la información de implementación de iPhone / iPad).

Es básicamente una GUI para establecer el archivo plist