MPMoviePlayerViewController no gira automáticamente

Tengo un comportamiento extraño en el que MPMoviePlayerViewController no gira auto cuando cambia la orientation . Sin embargo, recreaba la misma jerarquía de vista en un proyecto nuevo y cuando el reproductor MPMoviePlayerViewController estaba activo, giraba a cada orientación. He rastreado el proyecto buscando algo que pueda estar configurando la orientación explícitamente, pero no hay nada.

Explicaré toda la información relevante aquí y las cosas que he intentado hasta ahora.

La jerarquía de vistas actualmente se ve así:

  • Controlador de navigation
  • "Root" View Controller <- controller de navigation 'rootViewController'
  • Controlador de vista "Feed" <- Empujado en la stack de navigation por el Root VC
  • "Vista previa" Controlador de vista <- Presentado como un VC modal desde el Feed
  • MPMoviePlayerViewController Subclass <- presentado por Feed VC a través de 'presentMoviePlayerViewControllerAnimated'

Cada class en la jerarquía de vista responde a shouldAutorotateToInterfaceOrientation con YES solo para UIInterfaceOrientationPortrait.

Cosas que he probado:

  • Enviando manualmente la stack de shouldAutorotateToInterfaceOrientation desde el VC "Root" hasta el MPMoviePlayerViewController
  • MPMoviePlayerViewController la implementación de la subclass MPMoviePlayerViewController 'de shouldAutorotateToInterfaceOrientation para devolver YES para ambas orientaciones de paisaje y YES para todas las orientaciones.
  • Configurar 'Orientación de dispositivo admitido' en la pestaña de resumen del proyecto.
  • Llamar al presentMoviePlayerViewControllerAnimated de otros VC como el Feed VC

Si el reproductor de películas gira correctamente en un proyecto nuevo con la misma jerarquía de vista, lo que podría estar interponiéndose en el path. ¿Alguna idea de dónde se podría estancar la orientación?

Le sugeriré que no use presentMoviePlayerViewControllerAnimated , en lugar de agregar como subvista. Creo que arreglará tu problema muy bien.

 MPMoviePlayerViewController *mpviewController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:self.filePath]]; [self.view addSubview:mpviewController.view]; [self setWantsFullScreenLayout:YES]; 

Y elimine mpviewController.view cuando se detecte MPMoviePlayerPlaybackDidFinishNotification . Déjame ver tu éxito …

He encontrado que los objects MPMoviePlayerViewController respetarán las configuraciones de Info.plist del proyecto para las orientaciones de interfaz admitidas. En un proyecto mío, solo estaba permitiendo vistas panorámicas en ese file para que el reproductor de películas no rotara, incluso cuando respondía YES a las orientaciones de paisaje en shouldAutorotateToInterfaceOrientation:

Edit: OK, aferrándose a pajas: ¿implementas automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers UIViewController en cualquiera de tus subclasss UIViewController ? Si es así, y devuelve NO , sus subclasss deben reenviar los methods apropiados a los controlleres secundarios según el cambio de orientación.

De lo contrario, ¿hay alguna manera de ver tu código?

Sé que esta podría ser una sugerencia estúpida, pero asegúrese de que se shouldAutorotateToInterfaceOrientation método shouldAutorotateToInterfaceOrientation en su subclass MPMoviePlayerViewController . Tal vez algo salió mal allí …

También asegúrese de no tener 2 subidas agregadas a la UIWindow principal como se especifica aquí :

P: ¿Por qué mi UIViewController no gira con el dispositivo?

[…]

  • La propiedad UIView del controller de vista está incrustada dentro de UIWindow pero junto con un controller de vista adicional.

Creo que eso también te puede dar algunos problemas. Puede encontrar más información sobre lo que podría salir mal en el enlace de arriba.

Algunas ideas:

  • ¿El UINavigationController establece como la propiedad rootViewController la rootViewController de su aplicación? No mencionaste eso. Debe hacer esto en lugar de agregar la vista del controller de navigation a la window.
  • En caso de que esté construyendo toda la jerarquía a la vez, intente descomponerla. Puede agregar un button a cada etapa que agrega el siguiente controller de vista a la jerarquía.
  • Intenta eliminar cualquier animation de la construcción de la jerarquía del controller de vista. Hacer varias animaciones al mismo time podría ser un problema. Por ejemplo, no está permitido empujar dos controlleres de vista en un UINavigationController uno tras otro, con animated:YES . Es posible que tenga un problema similar.
  • Asegúrese de build toda la jerarquía del controller de vista en el hilo principal.
  • Asegúrate de que no haya otro controller de vista que "se haga cargo" de la rotation (como escribió @MihaiFratu, esto es un motivo tan común para los problemas de rotation que tuve que repetir :-)).

Solución:

Para cualquiera que pueda encontrar esto, la razón por la cual el video no estaba girando era que accidentalmente estaba agregando RootViewController tiene el rootViewController de la window, en lugar del UINavigationController.

 self.window.rootViewController = navController; 

es correcto

self.window.rootViewController = rootViewController;

no es

Gracias chicos por su ayuda y aportes en el path.

¿Estás usando storyboards? Compare la configuration de orientación de UIViewControllers y su UINavigationController entre su proyecto roto y su proyecto de testing. La configuration de "Orientación" en el inspector de attributes puede estar bloqueando una orientación.

Usted mencionó shouldAutorotateToInterfaceOrientation: y su configuration de plist así que no entraré en eso …

hay algunos motivos detrás de su consulta …

*** Usted está llamando a MPMoviePlayerViewController .. entonces aplique AutoOrientation en "Feed" View Controller e intente llamar por PushViewController ..

*** Utilice MPMoviePlayerController lugar de MPMoviePlayerViewController y agregue subvista en FeedViewController ..

Código de ejemplo para MPMoviePlayerController–

 NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"filename" ofType:@"type"]]; videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url]; videoPlayer.controlStyle = MPMovieControlStyleNone; videoPlayer.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width); [videoPlayer prepareToPlay]; videoPlayer.view.center = self.view.center; videoPlayer.fullscreen = YES; [self.view addSubview:videoPlayer.view]; [videoPlayer play]; 

*** Verifique la configuration de destino de Xcode y aplique la habilitación de todas las orientaciones.

Tuve un problema similar.

Resuelto por:

  1. habilitando todas las orientaciones en Orientaciones de interfaz admitidas (Objetivo> Resumen)
  2. ahora su aplicación comenzará a rotar en todas las Orientaciones, si no desea esto, omita el paso 1, solo agregue el siguiente método en la aplicaciónDelegate

    • (NSUInteger): aplicación (UIApplication *) soportadaInterfaceOrientationsForWindow: window (UIWindow *) {return UIInterfaceOrientationMaskAll; }
  3. Eliminar shouldAutorotateToInterfaceOrientation en todas partes

  4. agregando el siguiente método para ver el controller para respaldar las Orientaciones que necesita para su aplicación

    • (NSUInteger) soportadoInterfaceOrientations {return UIInterfaceOrientationMaskPortrait; }
  5. puede agregar el mismo método que en el paso 4 en la subclass MPMoviePlayerViewController para las orientaciones que necesite para el reproductor de video

Deberías probar esto (trabajado para mí):

Declare en el file .h:

 BOOL landscape; 

Archivo .m:

 -(IBAction)PlayMovie:(NSString *)movieName { landscape = YES; NSBundle *bundle = [NSBundle mainBundle]; NSString *moviePath = [bundle pathForResource:movieName ofType:@"mp4"]; NSURL *movieURL = [NSURL fileURLWithPath:moviePath]; MPMoviePlayerController *theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; theMovie.scalingMode = MPMovieScalingModeAspectFill; [theMovie play]; MPMoviePlayerViewController *moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL]; [self presentMoviePlayerViewControllerAnimated:moviePlayer]; } -(void)dismissMoviePlayerViewControllerAnimated { landscape = NO; [self dismissModalViewControllerAnimated:YES]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // You can change the return for your needs. if (landscape == YES) { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } else { return NO; } } 

Lo que hice aquí es crear mi vista de película y establecer el "paisaje" BOOL en SÍ.

Luego, "shouldAutorotateToInterfaceOrientation" detectará esto y autorotará su vista.

Y cuando termina la película, coloco el "paisaje" en NO para que la vista gire hacia atrás.

esta guía me ayudó a verificar algunos pasos que me faltaban para permitir que solo se vea el reproductor de video en el paisaje, dejando que el rest de la aplicación se fije en modo vertical:

iOS6 y consejo de autorotation

Tuve mucho dolor con MPMoviePlayerViewController, que debería ser solo un controller capaz de rotar de retrato a paisaje y viceversa. Era la aplicación iOS7, iOS8 con storyboard.

Aquí hay una solución:

  1. La aplicación debe habilitar todas las orientaciones requeridas. Como en la imagen
  2. Cada UIViewController que necesita soportar solo el modo vertical, debe implementar los siguientes methods, como este

     -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 
  3. MPMoviePlayerViewController debe extenderse y los siguientes methods deben ser anulados como este

     -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; } 
  4. Use presentMoviePlayerViewControllerAnimated para mostrar MPMoviePlayerViewController

Agregue este método en AppDelegate.m

– (NSUInteger) aplicación: (UIApplication *) aplicación soportadaInterfaceOrientationsForWindow: window (UIWindow *) {

 if(!ISIPAD) { if ([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]] && ![[self.window.rootViewController presentedViewController] isBeingDismissed]) { return UIInterfaceOrientationMaskAllButUpsideDown; } else { return UIInterfaceOrientationMaskPortrait; } } return UIInterfaceOrientationMaskAllButUpsideDown ; 

}