【问题标题】:In UISplitViewController, can't make showDetailViewController:sender: push onto detail navigationController在 UISplitViewController 中,不能让 showDetailViewController:sender: push on detail navigationController
【发布时间】:2014-09-26 05:03:23
【问题描述】:

在 iOS 8 中,视图控制器现在可以调用 showDetailViewController:sender: 让系统确定正确的视图控制器来呈现详细视图控制器。

在我的应用程序中,我有一个 UISplitViewController,它的 viewControllers 数组中包含两个 UINavigationControllers。第一个 UINavigationController 包含我的“主”视图,它是 UITableViewController 的子类。第二个 UINavigationController 包含我的“详细”视图。

由于我正在尝试使这项工作普遍适用,因此我正在尝试使用showDetailViewController:sender: 来显示详细视图:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    self.itemVC.item = self.itemStore.items[indexPath.row];

    [self showDetailViewController:self.itemVC sender:self];
}

self.splitViewController.collapsed == YES 时,这适用于水平紧凑特征(iPhone 风格),但当特征为常规时(iPad,未折叠)则不行。在 iPad 上,它用裸细节视图控制器替换了细节 UINavigationController(而不是替换那个 UINavigationController 的 viewControllers 数组)。

为了解决这个问题,我测试了它是否已折叠,如果没有,我将在显示之前将详细视图控制器包装在另一个 UINavigationController 中:

- (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];
}

我想我也可以只配置self.itemVC 并避免在self.splitViewController.collapsed == NO 时完全调用showDetailViewController:sender:

- (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];
    }
}

但是,这感觉违背了showDetailViewController:sender: 的目的,即放松self 与视图层次结构的其余部分之间的耦合。

有没有更好的方法来处理这个问题?

【问题讨论】:

  • 您在这方面取得了进展吗?我也有同样的问题。
  • 不-我仍在做我结束帖子的事情。但我不喜欢它。
  • 顺便说一句,在最新的测试版中,即使您在 iPhone 上运行,您也可以推送 NavigationController。您只会看到一个导航栏。他们隐藏了最里面的 UINavigationController 的 navigationBar。
  • 是的,我看到了 - 它有效,但我认为它没有正确地从堆栈中弹出?我不记得了,但我记得我对那个解决方案没有任何感觉。

标签: ios objective-c uinavigationcontroller uisplitviewcontroller ios8


【解决方案1】:

showDetailViewController:sender: 中,根据collapse 属性,您需要创建要详细显示的控制器。

例如在 iPad 的横向模式下,它已经从情节提要中创建了细节视图控制器,但在 iPhone 5 上它折叠起来的视图控制器还不存在。

- (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];
}

希望这能解决您的问题。

【讨论】:

    【解决方案2】:

    你做这件事的方式有问题。如果您在选择后旋转设备(将模式从折叠模式更改为 allVisible),您会发现没有导航控制器的详细信息 vc。

    如果您在所有情况下都调用showDetailViewController:sender: 并使用导航控制器传递视图控制器,那么它在两种情况下都可以正常工作,并且还可以解决上述旋转问题。

    - (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];
    }
    

    【讨论】:

      【解决方案3】:
      if (self.splitViewController.collapsed)
          [self.splitViewController showDetailViewController:self.itemVC sender:self];
      else
          self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;
      

      【讨论】:

        猜你喜欢
        • 2011-12-23
        • 2018-11-02
        • 1970-01-01
        • 1970-01-01
        • 2018-04-27
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 1970-01-01
        相关资源
        最近更新 更多