2014-01-09 40 views
1

我正在使用控制器包含API实现自定义的segue,没有presentViewController的自定义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[UIStoryboardUnwindSegueTemplate _perform:]有例外Could not find a view controller to execute unwinding for <…>

展开到sourceViewController,应用程序崩溃我没有实现自定义-[UIViewController viewControllerForUnwindSegueAction:fromViewController:withSender:-[UIViewController canPerformUnwindSegueAction:fromViewController:withSender:这意味着框架返回正确的值(虽然我实现了它一次检查)。

在segue中将我的自定义addChildViewController:…代码替换为presentViewController:…时,它工作正常:展开按预期执行。

问题:是否有可能创建自定义视图控制器层次结构的自定义segue?

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

+0

不要认为它会解决您的问题,但是......您应该确实有一个包含源控制器的容器控制器,然后将目标控制器添加到容器中。然后做动画,然后删除源控制器。将目标控制器添加到源控制器有点奇怪。下面是一个执行的例子,它可以正确调用正确的东西,并更改视图控制器层次http://pastebin.com/Vk9JfcmP。可能有些用处? –

+0

它并没有真正改变代码崩溃的事实:)目前,层次结构对我而言并不重要 –

+0

可能是因为腐败的层次结构导致问题,尽管... –

回答

0

我认为乔治格林的评论是相关的,你有你的控制器设置方式是飞机失事的原因。我认为要做你想做的事情,你应该把ZTSFirstViewController作为一个子元素添加到自定义的容器控制器中,它将完成展开,而(forward)segue将交换该自定义容器控制器的子元素(从ZTSFirstViewController切换到ZTSSecondViewController)。 viewControllerForUnwindSegueAction:fromViewController:withSender:方法需要在自定义容器控制器(在我的示例中为ViewController)中实现。我通过在ViewController中添加IB的容器视图来测试这一点,并将嵌入式控制器的类更改为ZTSFirstViewController。我从ZTSFirstViewController中的一个按钮添加了一个segue到ZTSSecondViewController,并从该控制器中的一个按钮连接了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接近您的实现 - 它实际上并没有切换控制器,它只是增加了第二个作为第二个孩子和隐藏的观点首先。

+0

谢谢你的回答rdelmar,我也试过了。我想我没有正确地说我的问题,我当前的设置工作,如果自定义赛格替换内置的,那是什么原因造成的问题。苹果公司在2012年的wwdc上展示了它(视频407,最近10分钟)如何通过根控制器实现segues + unwinding。他们的设置非常相似:http://d.pr/i/eefI。所以,除非我错过了一些东西,问题仍然存在:是否有可能在根视图控制器中通过segue添加子视图控制器并通过展开将其删除。 –

+0

@SashaZats,当我有更多时间的时候,我会再看看那个视频。在这种情况下,我看不出有什么好处。父母和孩子之间已经有了对方的引用,所以将数据发送回父母并不成问题 - 我认为使用展开的主要优点之一是将数据发送回遥控器,在遥控器中很难设置正常的委托模式,或者返回几个控制器,在这些控制器中,您已经推出了推送和呈现的混合体。 – rdelmar