2011-01-19 27 views
6

Estoy tratando de mostrar un UISplitViewController presentándolo como un controlador de vista modal en mi aplicación de iPad. Logré que se muestre, pero por alguna razón hay un espacio a la izquierda de la vista modal del tamaño de una barra de estado que también se conserva cuando se cambia la orientación.¿Cómo usar un UISplitViewController como un controlador de vista modal?

alt text

¿Alguien sabe por qué ocurre esto? O si esto es posible? Tal vez estoy cavando un gran agujero.

Respuesta

6

La acción UISplitViewController se diseñó para usar como controlador de visualización de raíz solamente. Presentar uno de manera modal va en contra de las Pautas de la interfaz humana de Apple y tiene una alta probabilidad de ser rechazado por el equipo de revisión de la aplicación. Además, puede recibir el siguiente error:

Application tried to present Split View Controllers modally

+2

una alternativa es tratar un controlador del mercado de accesorios SplitView en el tamaño, tales como https://github.com/SlavaBushtruk/APSplitViewController –

+1

upvoted para "controlador de vista del mercado de accesorios" –

3

Técnicamente, esto es lo que hice:

1/Subclase un UIViewController decir. @interface aVC: UIViewController

2/En viewDidLoad, configure un splitViewController, es decir. aSplitVC

3/Entonces self.view = aSplitVC.view

Después de todo, el presente AVC como modalViewController

+0

no funciona en Xcode 8, iOS 8+ Hay un registro de errores: "¡Una vista solo puede asociarse con un controlador de vista como máximo a la vez!" – Jerome

3

Estoy de acuerdo con Evan que esto es un poco fuera de color para Apple, pero yo era capaz de completar una versión de trabajo de esta con la siguiente solución:

UISplitViewController *splitVC = [[UISplitViewController alloc] init]; 
    splitVC.delegate = VC2; 
    splitVC.viewControllers = [NSArray arrayWithObjects:navcon1, navcon2, nil]; 

    UINavigationController *splitNavCon = [[UINavigationController alloc] init]; 
    splitNavCon.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    [splitNavCon.view addSubview:splitVC.view]; 
    VC2.splitParentViewController = splitNavCon; 

    [self presentViewController:splitNavCon animated:YES completion:nil]; 

esto me permitió tener un botón de trabajo de nuevo en la nueva UISplitViewController que fue presentado en la pantalla de forma modal.

Notarás que paso realmente el VC2 (el delegado de UISplitViewController) su UINavigationController principal. Esta fue la mejor forma en que descubrí que podía descartar la UISplitViewController desde dentro del VC2:

[splitParentViewController dismissViewControllerAnimated:YES completion:nil]; 
+1

La idea básica aquí funciona bastante bien, pero ARC puede comer el 'UISplitViewController' si algo más no lo está reteniendo. Entonces, si los hijos de su vista desaparecen después de haber sido presentados de esta manera, muévalos a una propiedad o algo así. – Nuthatch

8

Al igual que para muchos de ustedes, que necesitaba una 'forma modal' utilizar el UISplitViewController. Esto parece ser un problema antiguo, pero todo lo que encontré en StackOverflow fue, en el mejor de los casos, una explicación de por qué el problema ocurre cuando intentas hacerlo (como la respuesta aceptada anteriormente) o "hack-arounds".

Sin embargo, a veces tampoco es muy conveniente cambiar gran parte de su base de código y hacer que UISplitViewController sea el objeto inicial solo para que su funcionalidad esté en funcionamiento.

En efecto, hay una manera de hacer felices a todos (incluidas las pautas de Apple). La solución que mejor que encontré, era utilizar el UISplitViewController normalmente, pero cuando es necesario para ser mostrado/despedidos, utilice el siguiente enfoque:

-(void)presentWithMasterViewController: (UIViewController *) thisMasterViewController 
    andDetailViewController: (UIViewController *) thisDetailViewController 
         completion:(void(^)(void))completion 
{ 
    masterViewController = thisMasterViewController; 
    detailViewController = thisDetailViewController; 

    [self setViewControllers:[NSArray arrayWithObjects:masterViewController, detailViewController, nil]]; 

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 

    self.window.rootViewController = self; 

    [self.window makeKeyAndVisible]; 

    if(completion) 
     completion(); 
    } 

-(void)dismissViewControllerWithCompletion:(void (^)(void))completion 
{ 
    self.window = nil; 
    masterViewController = nil; 
    detailViewController = nil; 
    if(completion) 
     completion(); 
} 

Donde "ventana", es una propiedad de la subclase UISplitViewController. ¡Y el sistema se encargará del resto!

Para mayor comodidad/de referencia, he subido esto como una subclase UISplitViewController a GitHub:

ModalSplitViewController

--example EN MODO DE EMPLEO -

mySplitViewController = [[ModalSplitViewController alloc] init]; 
    mySplitViewController.delegate = self; 

    [mySplitViewController presentWithMasterViewController:masterViewController andDetailViewController:detailViewController completion:nil]; 

    // when done: 

    [mySplitViewController dismissViewControllerWithCompletion:nil]; 
    mySplitViewController = nil; 

Side-nota: supongo la mayor parte de la confusión proviene del hecho de que el ejemplo de uso UISplitView de la documentación de Apple usa la ventana creada en la aplicaciónDelegate, y por el hecho de que la mayoría de las personas no están tan familiarizado con el concepto de ventana, porque normalmente no necesitamos para (se crean una vez en StoryBoards o en un código repetitivo).

Además, si está restaurando el estado, no debe olvidar que el sistema no restaura automáticamente los UIViewControllers creados mediante programación. El sistema no restaurará automáticamente .

0

Creo que se puede hacer al revés: en lugar de controlador personalizado con controlador dividido, uno puede configurar el controlador dividido como el controlador de la ventana raíz en el guión gráfico, y en la parte superior puede agregar su controlador personalizado (es decir, pantalla de inicio de sesión) y eliminarlo de la pantalla (removeFromSuperview por ejemplo) cuando sea necesario.

0

Esa respuesta no es en realidad correcta, porque ya no es válida desde iOS8 y si necesita soportar incluso iOS7 puede hacer eso como poner realmente modalmente UIViewController que tiene un contenedor como SplitView.

let mdSplitView = self.storyboard?.instantiateViewControllerWithIdentifier("myDataSplitView") as! MyData_SplitVC 
    self.addChildViewController(mdSplitView) 

    mdSplitView.view.bounds = self.view.bounds 
    self.view.addSubview(mdSplitView.view) 
    mdSplitView.didMoveToParentViewController(self) 
Cuestiones relacionadas