ipad uiviewcontroller uisplitviewcontroller modalpopups

ipad - Problema después de descartar una vista modal utilizada junto con un controlador uisplitviewcontroller



uiviewcontroller modalpopups (5)

Me está costando entender por qué está sucediendo lo siguiente (y cómo solucionarlo).

Creé una aplicación usando la aplicación basada en vista dividida.

He agregado un UiBarButtonItem llamado showTheModal que llama a este método que se encuentra en RootViewController.m:

- (IBAction)showTheModal:(id)sender { theModalController.modalPresentationStyle = UIModalPresentationFullScreen; theModalController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentModalViewController:theModalController animated:YES]; if ([detailViewController popoverController] != nil) [[detailViewController popoverController] dismissPopoverAnimated:YES];

El elemento BarButton, por supuesto, se muestra en la parte inferior del controlador raíz predeterminado (el lado izquierdo de la vista dividida en el paisaje) o en la parte inferior de la ventana emergente (si está en el paisaje).

La vista modal se descarta mediante un botón ubicado en una barra de herramientas. Llama a lo siguiente:

[self dismissModalViewControllerAnimated: YES];

El problema que tengo es si gira la pantalla, mientras que el modal está arriba. Esto es lo que sucede en diferentes escenarios (inicio se refiere a la orientación cuando se golpea el botón showTheModal, end se refiere a la orientación cuando presiono el botón de descartarModal).

1) Comenzar paisaje, paisaje final: todo parece estar bien. Los métodos willHideViewController y willShowViewController no se invocan en RootViewController (como se esperaba)

2) Comenzar paisaje, retrato final: la interfaz de usuario parece estar bien. willHideViewController se ejecuta DOS VECES (¿POR QUÉ?)

3) Retrato de inicio, retrato final: la interfaz de usuario parece estar bien. willHideViewController se ejecuta una vez (como se esperaba)

4) Comenzar retrato, paisaje final: el botón "Lista raíz" permanece en la vista de detalles (lado derecho de la vista dividida. No se invocarán los controles "Ocultar vista" y "Mostrar control visual" (¿POR QUÉ?)

¿Alguna idea de por qué los números 2 y 4 no se comportan del modo esperado?


Creo que este es un error que debe ser reportado a Apple Development.

Trabajé en parte de este problema presentando mi vista modal usando el formato UIModalPresentationPageSheet .


Estaba teniendo el mismo problema exacto.

En respuesta a (2), parece ser un error. Observé que cuando una vista modal se desplaza sobre una vista dividida, los mensajes de orientación se ponen en cola en algún lugar y no se procesan hasta que se descarta la vista modal y la vista dividida está visible, pero aún esperaría obtener solo una devolución de llamada.

Para (4), esto también parece ser un error. Afortunadamente, los eventos didRotate ... todavía se procesan, así que mi solución fue crear una subclase de UISplitViewController y llamar explícitamente al método willShowViewController del delegado en este caso:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; //Work around a bug where UISplitViewController does not send //willShowViewController after a modal is presented in portrait //but dismissed in landscape. UIInterfaceOrientation orientation = self.interfaceOrientation; if ( (orientation == UIInterfaceOrientationLandscapeLeft ) || (orientation == UIInterfaceOrientationLandscapeRight) ) { UINavigationItem* item = [detail.navigationBar.items objectAtIndex:0]; UIBarButtonItem* barButtonItem = [item leftBarButtonItem]; [super.delegate splitViewController:self willShowViewController:master invalidatingBarButtonItem:barButtonItem]; } }

Aquí, "maestro" es un IBOutlet que se refiere al controlador de vista maestro (lado izquierdo) de la vista dividida y "detalle" es un IBOutlet para el controlador de vista detallada (tamaño de la mano derecha).

Tenga en cuenta que en mi caso, la vista de detalle es un UINavigationController. Puede requerir un código diferente para obtener barButtonItem de su controlador de vista.

Además, esto tiene el efecto secundario de llamar a willShowViewController dos veces para la rotación normal, pero eso no es un problema en mi caso.


He tenido exactamente el mismo problema (n. ° 4, arriba). Trabajé alrededor usando viewDidAppear:animated , y luego verificando el alto de la vista para ver si está en el paisaje frente al retrato. (Yuck, gag, etc.) No estoy satisfecho en absoluto con esa "solución".

Posiblemente relacionado: me he dado cuenta de que el botón en modo retrato desaparece lentamente después de rotar a horizontal, es decir, el botón aparece por un segundo después de que termina la rotación. Sin embargo, en Mail.app, el botón "Bandeja de entrada" desaparece tan pronto como comienza la rotación. ¿Apple está haciendo las cosas de forma diferente de lo que recomiendan en sus documentos? Quizás haya una forma más eficiente de mostrar / ocultar el botón de vista maestra?


Lamentablemente, esto no es un error. Parece ser un comportamiento esperado.

Encontré esto en iOS Release Notes para iOS 5.0, en la sección "Notas y problemas conocidos":

Las devoluciones de llamadas de rotación en iOS 5 no se aplican para ver los controladores que se presentan en una pantalla completa. Lo que esto significa es que si su código presenta un controlador de vista sobre otro controlador de vista, y luego el usuario gira el dispositivo a una orientación diferente, al momento del rechazo, el controlador subyacente (es decir, el controlador que presenta) no recibirá ninguna devolución de llamada de rotación. Sin embargo, tenga en cuenta que el controlador que se presenta recibirá una llamada a viewWillLayoutSubviews cuando se vuelva a mostrar, y la propiedad interfaceOrientation se puede consultar desde este método y se puede usar para diseñar el controlador correctamente.


Para el diagnóstico, ¿ha intentado descartar primero la vista de popover? ¿O inicia sesión quién llama al método imprimiendo (id) sender ?