2012-05-03 11 views
25

En una aplicación para iPad, estoy usando el UISplitViewController. Necesito forzar para mostrar el master popover cuando la aplicación se inicia en modo retrato.UISplitViewController: ¿Cómo fuerza mostrar master popover en el lanzamiento de la aplicación? (retrato)

Ahora estoy usando este código y funciona bien en iOS 5.0.

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 
    if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) { 
     [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]; 
    }    
} 

Pero en iOS 5.1 (con el nuevo tipo de master popover) el comportamiento parece ser aleatorio. A veces, el popover se muestra en pantalla completa y, a veces, funciona bien.

¿Alguna sugerencia para 5.1?

+1

Aquí hay una buena respuesta: http://stackoverflow.com/a/15817100/733862 – akofink

Respuesta

13

Luché con este por un tiempo, y aún ahora no estoy 100% satisfecho con la solución, pero es lo único que he podido encontrar, dadas las limitaciones actuales.

En primer lugar, anular el siguiente método delegado:

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController 

y utilizarlo para tomar una referencia al elemento de botón de la barra, y almacenarlo en una Ivar:

barButtonForMaster = barButtonItem; 

Entonces, cuando desea mostrar el controlador de vista maestro, realice una llamada como esta:

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster]; 

En caso de que desee por formar esta justo al comienzo, a continuación, utilizar un cierto retraso con el fin de evitar la aplicación de estrellarse (gracias al comentario útil):

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1]; 

En ese caso se puede realizar el selector hacia la derecha en el método delegado vista dividida.

+1

Gracias. Lo hago con su código más mi código anterior. Pero a veces la aplicación falla. Creo que es porque hago eso en el delegado splitViewController y, quizás, en algunos casos, el controlador no está completamente creado. Ahora hago ese código con perfromSelectorAfterDelay y trabajo muy bien. Gracias. – alejandromp

+0

Esto dará como resultado una advertencia de pérdida de memoria del compilador posible – anders

13

Extendiéndose sobre la respuesta de Rob, esto funciona bien para mí (en viewDidLoad de pantalla de detalles):

//If in portrait mode, display the master view 
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem]; 
} 

No hay necesidad de buscar una referencia por separado, utilizando self.navigationItem.leftBarButtonItem lugar

+0

¡esto es asombroso y funciona perfectamente! sin embargo, me está dando una advertencia: "PerformSelector puede causar una fuga porque su selector es desconocido", ¿sabría por qué y qué hacer al respecto? – bllubbor

+2

AFAIK el compilador analiza las llamadas al método y agrega código para administrar los contadores de referencia ARC (para gestionar la recolección de basura). Llamar a un método como este es como usar reflejos en Java (hecho durante el tiempo de ejecución), por lo que el compilador no puede hacer su magia refCount en este caso. Sin embargo, siempre que el método llamado no devuelva ningún objeto asignado (que luego sería una fuga) no habrá ningún problema. En este caso, no estamos devolviendo nada del método llamado. Para evitar esta advertencia, consulte: http://www.learningipadprogramming.com/2012/04/03/how-to-ignore-performselector-leak-warning/ – Setomidor

+1

gracias increíbles. – bllubbor

5

Si necesitarlo en el lanzamiento de aplicaciones, reemplazar este método en el controlador de vista de detalle:

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation 
{ 
    return NO; 
} 

Sin embargo, si este caso es necesario para ocultar posteriormente parece que la método no se llama, por lo que tendrá que ocultarlo manualmente.

+0

¡Gracias! Esta debería ser la respuesta aceptada. – Bill

+1

Esto está obsoleto en iOS 8. – phatmann

0

No hay necesidad de mantener referencias tontas al barButtonItem. Simplemente llame al mismo objetivo/acción. Véase mi respuesta https://stackoverflow.com/a/25695923/1021430

El objetivo es el controlador de vista dividida, y la acción es toggleMasterVisible:

+0

That toggleMasterVisible es un método privado. –

26

No se sugiere aquí por 5,1, pero uno de 8,0:

Ahora con iOS8, hay un montón de nuevos métodos para la configuración UISplitViewController.

En su caso, juste estableció el valor correcto en preferredDisplayMode, por ejemplo, en masterViewController viewDidLoad.

Objective-C:

- (void)viewDidLoad { 
    // configuring splitviewcontroller 
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; 

    //.... 
} 

Swift:

override func viewDidLoad() { 
     self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible 
    } 

Pero es de sólo el supuesto iOS8.

+5

Esto fuerza la visualización uno al lado del otro. No muestra la vista maestra en modo Popover como solicitó el OP. – phatmann

+0

@phatmann, no creo que alejandromp estuviera hablando de popover. Él dice * Necesito forzar para mostrar el maestro popover * pero eso no significa nada, de hecho. Teniendo en cuenta el contexto, habla de mostrar la vista maestra una al lado de la otra en modo retrato, como en paisaje. – Martin

+0

también se puede llamar en detalleViewController – fujianjin6471

7

Para iOS8 la forma más sencilla es la siguiente:

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay; 

yo uso esto cuando la aplicación se inicia la primera vez para mostrar log-in en MasterViewController. En todos los otros casos que utilizo

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic 
1

Una variación ligeramente menos hacky (rápido):

let btn = self.splitViewController!.displayModeButtonItem() 
btn.target?.performSelector(btn.action, withObject: btn) 
1

I utilizar esta solución:
En splitViewController en viewDidLoad conjunto displayMode a .primaryOverlay

override func viewDidLoad() { 
    if self.isCollapsed == false, self.displayMode == .primaryHidden { 
     self.preferredDisplayMode = .primaryOverlay 
    } 
} 

Y en viewWillAppear, configúrelo nuevamente en .automatic

override func viewWillAppear(_ animated: Bool) { 
    self.preferredDisplayMode = .automatic 
} 

Esta vista maestra de manera se mostrará al iniciar UISplitViewController y tendrá un comportamiento predeterminado después de la orientación cambiará.

Cuestiones relacionadas