Cómo hacer que MPMoviePlayerViewController comience en modo horizontal pero que aún permita cambios en la orientación

Hay una multitud de preguntas relacionadas con el locking de la reproducción de películas en modo horizontal o con la reproducción horizontal de películas utilizando MPMoviePlayerViewController o MPMoviePlayerController. Ya tengo la funcionalidad landscape / portrait, y no quiero bloquear la reproducción en ninguno de los modos.

Lo que tengo es un código que utiliza MPMoviePlayerViewController como sugieren los documentos, esencialmente:

     MPMoviePlayerViewController * movieViewController = 
         [[MPMoviePlayerViewController alloc] initWithContentURL: url];
     [parentViewController presentMoviePlayerViewControllerAnimated: movieViewController];

Mi aplicación está bloqueada en su mayoría en modo vertical, pero este código presenta el controller de película de manera modal en su propia vista, y admite orientaciones vertical y horizontal. Todo lo cual es muy agradable.

Aquí está mi problema. El 99% de los videos que presentaré son videos panorámicos, y el código anterior inicia la reproducción de películas en modo vertical, ya que el usuario (posiblemente) está sosteniendo el dispositivo en modo vertical.

Lo que quiero es el comportamiento de la aplicación nativa de YouTube; que cuando presente el controller de película, primero se presenta en modo horizontal, lo que le solicitará al usuario que cambie la orientación de su dispositivo. Si luego quieren volver a retocar, pueden hacerlo. Cuando se termine la película (o se descarte), se descartará el controller de la vista de película y el dispositivo debe estar en modo vertical.

Parece imposible ocultar correctamente la barra de estado (está vinculada a los controles de pantalla completa, independientemente del estado de 'hideStatusBar' antes de iniciar la película), por lo que parece que get la barra de estado en el lugar correcto también debe ser un parte de esto

Editado para agregar notas de debugging para la orientación de la barra de estado : Si setStatusBarOrientation:UIInterfaceOrientationLandscapeRight a setStatusBarOrientation:UIInterfaceOrientationLandscapeRight antes de iniciar la película, la barra de estado está en el lugar correcto, pero el sistema ya no llama shouldAutorotateToInterfaceOrientation a la shouldAutorotateToInterfaceOrientation de la misma manera.

Si no setStatusBarOrientation , antes de que aparezca la película obtendré la siguiente secuencia de llamadas:

  shouldAutorotateToInterfaceOrientation (Retrato)
 shouldAutorotateToInterfaceOrientation (Retrato)
 shouldAutorotateToInterfaceOrientation (Retrato)
 shouldAutorotateToInterfaceOrientation (derecha)
 shouldAutorotateToInterfaceOrientation (Retrato) 

Respondo SÍ solo a la derecha, y la película se inicia en LandscapeRight, pero con la barra de estado en el lugar equivocado. Los cambios subsiguientes de la orientación del dispositivo generan exactamente las llamadas shouldAutorotateToInterfaceOrientation que esperas (por ejemplo, si giro a Portrait, me pregunta si está bien rotar a Portrait).

Si llamo a setStatusBarOrientation:UIInterfaceOrientationLandscapeRight , obtengo la siguiente secuencia:

  shouldAutorotateToInterfaceOrientation (derecha)
 shouldAutorotateToInterfaceOrientation (derecha) 

Ambas de las cuales respondo SÍ a. La barra de estado está en el lugar correcto, pero ya no recibo llamadas a shouldAutorotateToInterfaceOrientation preguntando sobre el modo de retrato. Así que si giro el dispositivo a la derecha, luego de vuelta a retrato, y luego de vuelta a la derecha, lo veo call shouldAutorotateToInterfaceOrientation(Right) dos veces. Aún más extraño, si lo gire por completo a la orientación de la Izquierda, obtendría shouldAutorotateToInterfaceOrientation(Left) y de ahí en adelante todo funciona bien . Lo que es más molesto.

Creo que debe ser un error en el lado de iOS, y es por eso que la aplicación de YouTube no utiliza los efectos de rotation de interfaz de usuario animados. En su lugar, oculta los controles de pantalla completa, incluida la barra de estado, gira de forma invisible en segundo plano y vuelve a mostrar los controles.

Sugeriría activar un timer; Permitir solo el paisaje en shouldAutorotateToInterfaceOrientation: al principio (lo que shouldAutorotateToInterfaceOrientation: a una rotation al paisaje), y luego (digamos) 5 segundos, permitir todas las orientaciones.

En primer lugar, necesita subclass MPMoviePlayerViewController o cree un MPMoviePlayerController en su propia vista. El código extra se vería así:

 // On load, init or similar method BOOL showLandscapeOnly = YES; NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@(allowAllOrientations) userInfo:nil repeats:NO]; - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if (showLandscapeOnly == YES) return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight); else return YES; } - (void)allowAllOrientations { showLandscapeOnly = NO; } 

Supongo que esto brindaría exactamente lo que buscas; Al mostrar el controller de video modal, voltearía la orientación al paisaje, ya que esta es la única orientación admitida. Pero si el usuario lo volvió a retocar, respondería bien.

También podría intentar experimentar con otros intervalos de time; quizás 2 segundos sería mejor? Sugiérale ver qué hacen los sujetos del usuario de testing. Probablemente giran el dispositivo bastante rápido.

¡Espero que ayude!

Tendrás que rotar el marco de la película y luego decirle al delegado de la aplicación que no se rote cuando oiga los posts de rotation.

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