objective-c swift ios8 uisplitviewcontroller

objective c - Ocultar el controlador de vista maestra con UISplitViewController en iOS8



objective-c swift (9)

El código a continuación oculta la vista maestra con animación

UIView.animateWithDuration(0.5) { () -> Void in self.splitViewController?.preferredDisplayMode = .PrimaryHidden }

Tengo una aplicación iOS7, que estaba basada en la plantilla de detalles maestros de Xcode, que estoy migrando a iOS8. Un área que ha cambiado mucho es UISplitViewController .

Cuando está en modo vertical, si el usuario toca el controlador de vista detallada, el controlador de vista maestra se descarta:

También me gustaría poder ocultar el controlador de vista maestra mediante programación si el usuario toca una fila.

En iOS 7, el controlador de vista maestra se mostró como una ventana emergente y podría ocultarse de la siguiente manera:

[self.masterPopoverController dismissPopoverAnimated:YES];

Con iOS 8, el maestro ya no es un popover, por lo que la técnica anterior no funcionará.

Intenté descartar el controlador de vista maestra:

self.dismissViewControllerAnimated(true, completion: nil)

O indique al controlador de vista dividida que muestre el controlador de visualización de detalles:

self.splitViewController?.showDetailViewController(bookViewController!, sender: self)

Pero nada ha funcionado hasta ahora. ¿Algunas ideas?


Extienda el UISplitViewController de la siguiente manera:

extension UISplitViewController { func toggleMasterView() { let barButtonItem = self.displayModeButtonItem() UIApplication.sharedApplication().sendAction(barButtonItem.action, to: barButtonItem.target, from: nil, forEvent: nil) } }

En didSelectRowAtIndexPath o prepareForSegue , haga lo siguiente:

self.splitViewController?.toggleMasterView()

Esto deslizará suavemente la vista maestra fuera del camino.

Tengo la idea de usar displayModeButtonItem () desde esta publicación y estoy simulando un toque en esta publicación .

No estoy muy contento con esta solución, ya que parece un truco. Pero funciona bien y parece que todavía no hay alternativa.


Mi solución en Swift 1.2

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){ var screen = UIScreen.mainScreen().currentMode?.size.height if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) || screen >= 2000 && UIDevice.currentDevice().orientation.isLandscape == true && (UIDevice.currentDevice().userInterfaceIdiom == .Phone){ performSegueWithIdentifier("showDetailParse", sender: nil) self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden } else if (UIDevice.currentDevice().userInterfaceIdiom == .Phone) { performSegueWithIdentifier("showParse", sender: nil) } }


Modificar las respuestas anteriores es todo lo que necesitaba en un método de mi controlador de vista detallada que configuraba la vista:

[self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModePrimaryHidden];

Por supuesto, carece de la gracia de la animación.


Pude tener el comportamiento deseado en un proyecto Xcode 6.3 Master-Detail Application (universal) agregando el siguiente código en el método MasterViewController ''s - prepareForSegue:sender: :

if view.traitCollection.userInterfaceIdiom == .Pad && splitViewController?.displayMode == .PrimaryOverlay { let animations: () -> Void = { self.splitViewController?.preferredDisplayMode = .PrimaryHidden } let completion: Bool -> Void = { _ in self.splitViewController?.preferredDisplayMode = .Automatic } UIView.animateWithDuration(0.3, animations: animations, completion: completion) }

La implementación completa de - prepareForSegue:sender: debería verse así:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "showDetail" { if let indexPath = self.tableView.indexPathForSelectedRow() { let object = objects[indexPath.row] as! NSDate let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController controller.detailItem = object controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() controller.navigationItem.leftItemsSupplementBackButton = true if view.traitCollection.userInterfaceIdiom == .Pad && splitViewController?.displayMode == .PrimaryOverlay { let animations: () -> Void = { self.splitViewController?.preferredDisplayMode = .PrimaryHidden } let completion: Bool -> Void = { _ in self.splitViewController?.preferredDisplayMode = .Automatic } UIView.animateWithDuration(0.3, animations: animations, completion: completion) } } } }

Usar traitCollection también puede ser una alternativa / complemento de displayMode en algunos proyectos. Por ejemplo, el siguiente código también funciona para un proyecto Xcode 6.3 Master-Detail Application (universal) :

let traits = view.traitCollection if traits.userInterfaceIdiom == .Pad && traits.horizontalSizeClass == .Regular { let animations: () -> Void = { self.splitViewController?.preferredDisplayMode = .PrimaryHidden } let completion: Bool -> Void = { _ in self.splitViewController?.preferredDisplayMode = .Automatic } UIView.animateWithDuration(0.3, animations: animations, completion: completion) }


Solo estoy mejorando un poco las respuestas enumeradas aquí, el siguiente código funciona correctamente para mí y también maneja la animación sin problemas:

extension UISplitViewController { func toggleMasterView() { var nextDisplayMode: UISplitViewControllerDisplayMode switch(self.preferredDisplayMode){ case .PrimaryHidden: nextDisplayMode = .AllVisible default: nextDisplayMode = .PrimaryHidden } UIView.animateWithDuration(0.5) { () -> Void in self.preferredDisplayMode = nextDisplayMode } } }

y luego, como se mencionó, solo usa la función extendida en cualquier lugar de sus controladores View

self.splitViewController?.toggleMasterView()


Use preferredDisplayMode . En didSelectRowAtIndexPath o prepareForSegue :

self.splitViewController?.preferredDisplayMode = .PrimaryHidden self.splitViewController?.preferredDisplayMode = .Automatic

Lamentablemente, la vista maestra desaparece bruscamente en lugar de deslizarse, a pesar de la documentación que indica:

Si al cambiar el valor de esta propiedad se produce un cambio real en el modo de visualización actual, el controlador de vista dividida anima el cambio resultante.

Con suerte, hay una mejor manera de hacer esto que realmente anima el cambio.


para iPad agrega el botón de Menú como este

UIBarButtonItem *menuButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"burger_menu"] style:UIBarButtonItemStylePlain target:self.splitViewController.displayModeButtonItem.target action:self.splitViewController.displayModeButtonItem.action]; [self.navigationItem setLeftBarButtonItem:menuButtonItem];

Este funciona muy bien con el modo paisaje y retrato. Para cerrar programáticamente el popover vc solo necesita forzar la acción del botón de esta manera

[self.splitViewController.displayModeButtonItem.target performSelector:appDelegate.splitViewController.displayModeButtonItem.action];


tratar

let svc = self.splitViewController svc.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden