没有presentViewController的自定义Segue不能正确展开

时间:2014-01-09 16:03:23

标签: ios objective-c uiviewcontroller uistoryboardsegue

我正在使用控制器包含API实现自定义segue,例如

@implementation CustomSegue

- (void)perform {
    UIViewController *sourceViewController = self.sourceViewController;
    UIViewController *destinationViewController = self.destinationViewController;

    [sourceViewController addChildViewController:destinationViewController];
    destinationViewController.view.alpha = 0.0;
    [sourceViewController.view addSubview:destinationViewController.view];
    [UIView animateWithDuration:0.3 animations:^{
        destinationViewController.view.alpha = 1.0;
    } completion:^(BOOL finished) {
        [destinationViewController didMoveToParentViewController:sourceViewController];
    }];
}

@end

查看控制器层次结构非常简单:sourceViewController → destinationViewController

destinationViewController展开到sourceViewController时,应用程序在[UIStoryboardUnwindSegueTemplate _perform:]中崩溃而异常Could not find a view controller to execute unwinding for <…>

我没有实现自定义-[UIViewController viewControllerForUnwindSegueAction:fromViewController:withSender:-[UIViewController canPerformUnwindSegueAction:fromViewController:withSender:这意味着框架返回正确的值(虽然我实现了一次以检查)。

在segue中使用addChildViewController:…替换我的自定义presentViewController:…代码时,它可以正常工作:展开会像预期的那样执行。

问题:是否可以使用自定义segue创建自定义视图控制器层次结构?

测试用例项目:https://bitbucket.org/zats/unwind/

1 个答案:

答案 0 :(得分:0)

我认为George Green的评论是相关的,你设置控制器的方式是导致崩溃的原因。我想要做你想做的事,你应该把ZTSFirstViewController作为一个孩子添加到一个自定义容器控制器,它将进行展开,而(forward)segue将交换该自定义容器控制器的子节点(从ZTSFirstViewController切换到ZTSSecondViewController)。 viewControllerForUnwindSegueAction:fromViewController:withSender:方法需要在自定义容器控制器(我的示例中为ViewController)中实现。我通过在IB中向ViewController添加容器视图来测试它,并将嵌入式控制器的类更改为ZTSFirstViewController。我从ZTSFirstViewController中的按钮向ZTSSecondViewController添加了一个segue,并从该控制器中的按钮连接了unwind segue。 unwind:方法在ZTSFirstViewController中。自定义segue中的代码就是这个,

- (void)perform {
        UIViewController *destinationViewController = self.destinationViewController;
        UIViewController *sourceViewController = self.sourceViewController;

        if (!self.unwind) {
            [sourceViewController.parentViewController addChildViewController:destinationViewController];
            destinationViewController.view.alpha = 0.0;
            [sourceViewController.parentViewController.view addSubview:destinationViewController.view];
            [UIView animateWithDuration:0.3 animations:^{
                destinationViewController.view.alpha = 1.0;
            } completion:^(BOOL finished) {
                [destinationViewController didMoveToParentViewController:sourceViewController.parentViewController];
            }];
        } else {
            [self.sourceViewController willMoveToParentViewController:nil];
            [UIView animateWithDuration:0.3 animations:^{
                sourceViewController.view.alpha = 0.0;
            } completion:^(BOOL finished) {
                [sourceViewController.view removeFromSuperview];
                [sourceViewController removeFromParentViewController];
            }];
        }
    }

我保持这个segue接近你的实现 - 它实际上没有切换控制器,它只是添加第二个作为第二个孩子并隐藏第一个的视图。