0

与模态视图和容器视图结合使用时,展开 segue 在 iOS 8.1 中的表现似乎不如预期。这是测试项目的视图控制器层次结构,可以在 github上找到:

展开 segue 错误层次结构图像

点击“点击我”按钮会推动嵌入在导航控制器中的模态视图,它有一个 tableView 作为子视图控制器。点击 tableView 中的一行会推送另一个 tableView。最后,点击这个最终 tableView 中的一行应该bUnwindSegue调用在前一个视图控制器上找到的 unwind segue 。

问题:

  1. bUnwindSegue 永远不会被调用。
  2. 根据技术说明TN2298,容器视图控制器负责选择子视图控制器来处理 segue。在这种情况下viewControllerForUnwindSegueAction:fromViewController:withSender:应该在容器视图控制器上调用。它不是。

在示例项目中,您可以看到其中BTableViewController包含 unwind segue:

- (IBAction)bUnwindSegue:(UIStoryboardSegue *)segue;
{
    NSLog(@"Unwinding...this unwind segue will never get called.");
}

在情节提要中,单元格选择动作CTableViewController确实是bUnwindSegue. 另请注意,如果您将单元格选择操作更改为CTableViewController容器视图控制器中的展开转场 -- containerVCUnwindSegue-- 转场被正确调用。

unwind segues 的行为是否不符合预期?

4

1 回答 1

0

(1)您误解了您引用的技术说明 TN2298,并且(2)您没有viewControllerForUnwindSegueAction:适当地覆盖。

正如您链接到的关于容器视图控制器的 TN2298 文档部分在其“选择子视图控制器以处理展开操作”子标题下声明:

您的容器视图控制器应覆盖 [viewControllerForUnwindSegueAction:] 中显示的方法,以在其子视图控制器中搜索想要处理展开操作的视图控制器。如果容器的子视图控制器都不想处理展开操作,它应该调用超级的实现并返回结果。

首先,要覆盖该方法,您必须UINavigationController在情节提要中继承该方法并在其中添加该viewControllerForUnwindSegueAction:方法。完成此操作后,您将看到该方法现在按预期调用。

但是您的第二个错误是您当前尝试覆盖该viewControllerForUnwindSegueAction:方法的尝试只是包含return self;. 相反,您应该返回要处理展开操作的视图控制器。

所以说,例如,你有一个公共变量VCWithContainedVCsViewController来保存当前的实例BTableViewController并且你访问你可以访问当前的容器视图控制器,例如:

- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
{
    NSLog(@"Technical note TN2298 indicates child VCs defer to their parent to determine where an unwind segue will be handled.");

    if ([NSStringFromSelector(action) isEqualToString:@"bUnwindSegue:"]) {

        NSLog(@"%@", self.viewControllers);
        VCWithContainedVCsViewController *containerVC = (VCWithContainedVCsViewController*)self.viewControllers[0];
        return containerVC.container;
    }

    return [super viewControllerForUnwindSegueAction:action fromViewController:fromViewController withSender:sender];
}

在这种情况下,您会看到它bUnwindSegue:实际上被调用(您的消息应该打印),但转场仍然不会发生。

为什么是这样?

因为正如我在评论中提到的,BTableViewController不在当前的导航堆栈上。的某些子视图控制器BTableViewController,例如CTableViewController,将位于导航堆栈上,因为例如,CTableViewController它不是容器视图。但BTableViewController它本身无法自行执行 segue,因为它不在当前导航堆栈上。因此,尽管您实际上可以选择一些子视图控制器来处理文档所述的展开操作,但BTableViewController不会成为其中之一。

于 2015-01-12T22:32:33.557 回答