ios objective-c uinavigationcontroller uisplitviewcontroller ios8

ios - En UISplitViewController, no se puede hacer showDetailViewController: remitente: presione el control de navegaciĆ³n detallado



objective-c uinavigationcontroller (3)

En showDetailViewController:sender: dependiendo de la propiedad de collapse que necesita para crear el controlador que desea mostrar en detalle.

Por ejemplo, en el iPad en modo horizontal ya crearía el controlador de vista de detalle desde el guión gráfico, pero en el iPhone 5 donde está contraído, el controlador 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.

En iOS 8, los controladores de vista ahora pueden llamar a showDetailViewController:sender: para que el sistema determine el controlador de vista adecuado para presentar el controlador de vista detallada.

En mi aplicación, tengo un UISplitViewController, que contiene dos UINavigationControllers en su matriz viewControllers. El primer UINavigationController contiene mi vista "maestra", una subclase de UITableViewController. El segundo UINavigationController contiene mi vista de "detalle".

Ya que estoy tratando de hacer que esto funcione universalmente, estoy tratando de usar showDetailViewController:sender: para mostrar la vista detallada:

- (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 está colapsado). En el iPad, reemplaza el detalle UINavigationController con el controlador de vista de detalle desnudo (en lugar de reemplazar la matriz viewControllers de UINavigationController).

Para solucionar esto, he probado si está colapsado o no, y si no lo está, estoy envolviendo el controlador de vista de detalle en otro controlador de control de UIN 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 configurar self.itemVC y evitar llamar a showDetailViewController:sender: conjunto 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 que está derrotando el propósito de showDetailViewController:sender: que es aflojar el acoplamiento entre self y el resto de la jerarquía de vistas.

¿Hay una mejor manera de manejar esto?


La forma en que lo haces tiene un problema. Si gira el dispositivo (cambie el modo de contraído a todo visible) después de seleccionar, encontrará el detalle vc sin un controlador de navegación.

Si llama a showDetailViewController:sender: en todos los casos y pasa el controlador de vista con un controlador de navegación, funcionará bien en ambos casos y también solucionará el problema de rotaion 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.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;