En UISplitViewController, no se puede hacer showDetailViewController: remitente: presione en detail navigationController

En iOS 8, los controlleres de vista ahora pueden llamar a showDetailViewController:sender: para que el sistema determine el controller de vista adecuado para presentar el controller de vista de detalle.

En mi aplicación, tengo un UISplitViewController, que contiene dos UINavigationControllers en su array viewControllers. El primer UINavigationController contiene mi vista 'master', una subclass de UITableViewController. El segundo UINavigationController contiene mi vista de "detalle".

Dado que estoy tratando de hacer que esto funcione de forma universal, bash usar showDetailViewController:sender: para mostrar la vista de detalle:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.itemVC.item = self.itemStore.items[indexPath.row]; [self showDetailViewController:self.itemVC sender:self]; } 

Esto funciona bien con el rasgo Compacto Horizontal (estilo iPhone), cuando self.splitViewController.collapsed == YES , pero no cuando el rasgo es Regular (iPad, no queuepsado). En el iPad, reemplaza el detalle UINavigationController con el controller de vista de detalles desnudos (en lugar de replace la matriz viewControllers de UINavagementController).

Para solucionarlo, estoy probado si está o no queuepsado, y si no lo está, estoy envolviendo el controller de vista de detalle en otro UINavigationController antes de mostrarlo:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.itemVC.item = self.itemStore.items[indexPath.row]; UIViewController *vcToShow; // For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it. if (self.splitViewController.collapsed) { vcToShow = self.itemVC; } else { vcToShow = [[UINavigationController alloc] initWithRootViewController:self.itemVC]; } [self showDetailViewController:vcToShow sender:self]; } 

Supongo que, alternativamente, podría simplemente configurar self.itemVC y evitar llamar a showDetailViewController:sender: completo cuando self.splitViewController.collapsed == NO :

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.itemVC.item = self.itemStore.items[indexPath.row]; // For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it. if (self.splitViewController.collapsed) { [self showDetailViewController:vcToShow sender:self]; } } 

Pero, esto parece ser que está venciendo el propósito de showDetailViewController:sender: que es aflojar el acoplamiento entre self y el rest de la jerarquía de la vista.

¿Hay una mejor manera de manejar esto?

En showDetailViewController:sender: según la propiedad collapse , debe crear el controller que desea mostrar en detalle.

Por ejemplo, en el iPad en modo horizontal, ya crearía el controller de vista de detalles desde el guión gráfico, pero en el iPhone 5, donde está queuepsado, el controller de vista aún no existe.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UINavigationController *detail; ImageViewController *imageVC; // on the iPhone (compact) the split view controller is collapsed // therefore we need to create the navigation controller and its image view controllerfirst if (self.splitViewController.collapsed) { detail = [[UINavigationController alloc] init]; imageVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ImageViewController"]; [detail setViewControllers:@[imageVC] animated: NO]; } // if the split view controller shows the detail view already there is no need to create the controllers else { id vc = self.splitViewController.viewControllers[1]; if ([vc isKindOfClass:[UINavigationController class]]) { detail = (UINavigationController *)vc; imageVC = [detail.viewControllers firstObject]; } } [self prepareImageViewController:imageVC forPhoto:self.photos[indexPath.row]]; // ask the split view controller to show the detail view // the controller knows on iPhone and iPad how to show the detail [self.splitViewController showDetailViewController:detail sender:self]; } 

Espero que esto resuelva tu problema.

La forma en que lo haces tiene un problema. Si gira el dispositivo (cambie el modo de queuepsado a todoVisible) después de seleccionar, encontrará el detalle vc sin un controller de navigation.

Si llama showDetailViewController:sender: en todos los casos y pasa el controller de vista con un controller de navigation, funcionará bien en ambos casos y también solucionará el problema de rotation mencionado anteriormente.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.itemVC.item = self.itemStore.items[indexPath.row]; UIViewController *vcToShow= [[UINavigationController alloc] initWithRootViewController:self.itemVC]; [self showDetailViewController:vcToShow sender:self]; } 
 if (self.splitViewController.collapsed) [self.splitViewController showDetailViewController:self.itemVC sender:self]; else self.splitViewController.prefernetworkingDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;