2014-01-09 65 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