2013-04-27 55 views
0

我想創建一個自定義的segue,它的作用方式與標準push segue在UINavigationController視圖控制器上使用時的作用相同。我實現了我的自定義賽格瑞:自定義segue將特定的UIViewController推送到UINavigationController

CustomSegue.m

-(void)perform { 
    UIViewController *source = (UIViewController *)[self sourceViewController]; 
    UIViewController *dest =(UIViewController *)[self destinationViewController]; 
    if (1==2 //test) { 
     [source.navigationController pushViewController:dest animated:YES]; 
    } 
    else { 
     UIViewController *altDest = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:NULL] 
     instantiateViewControllerWithIdentifier:@"alternateView"]; 
     [source.navigationController pushViewController:altDest animated:YES]; 
    } 

正如你所看到的,我想用一個自定義推賽格瑞的原因是,我可以決定哪些視圖控制器推基於用戶配置(目前只檢查一個微不足道的1 == 2表達式)。我可以在沒有問題的情況下實例化替代視圖控制器,但我希望能夠做的事是每次都重複加載視圖控制器(使用後退按鈕和下一個按鈕)來回移動。有沒有一種方法可以從故事板中檢索現有的實例,或者一些標準的方法來實現這一點?

回答

2

而是其perform定製賽格瑞的,順便做你的描述,即選擇在實時是否推destaltDest,或者是(1)不使用在所有塞格斯並調用pushViewController直接作爲你在這裏做,或者(2)準備從視圖控制器發出的兩個段落作爲一個整體,並且呼叫performSegueWithIdentifier:說我們應該執行哪一個。

至於直接從destaltDest,可以對dest頂推altDest然後從導航控制器的視圖控制器的堆疊移除dest

像這麼多關於iOS的東西,如果你根本不使用故事板,那麼這會變得更加容易和明顯。這就是爲什麼我不喜歡故事板:他們非常簡單和有限,而且他們注意力從iOS 真正的工作。

+0

下面是如何在代碼完全操作導航界面我的書的討論:http://www.apeth.com/iOSBook/ch19.html#_configuring_a_navigation_controller – matt 2013-04-27 16:18:33

+0

謝謝!成功管理您的工作和@ rdelmar的答案。我已經將「Next」按鈕操作更改爲標準IBAction,以便推送所需的視圖控制器而不是使用segues - 這樣,我可以將實例化視圖控制器存儲在堆棧中的前一個視圖控制器中,並在實例化視圖控制器時將其推送存在。我同意故事板掩蓋了很多正在發生的事情,這導致了對低層的理解不足。我會標記你的答案,當它讓我:) – 2013-04-27 16:47:54

+0

你可能想要嘗試'setViewControllers:animated:'。它可以讓你重新安排現有的視圖控制器*和*可能添加更多的視圖控制器,刪除現有的視圖控制器等,*和*它執行自動動畫(除非你不告訴它)。因此,您可以將兩個備用視圖控制器保留在堆棧中,並重新排列它們。 – matt 2013-04-27 16:56:44

0

無法從故事板中檢索現有的控制器 - 如果有controllerWithIdentifier:方法來執行此操作,但沒有方法,那將會很不錯。 Segmentation(除了unwinds)總是實例化新的控制器,所以我認爲你不能用segue做你想做的事情。如果您想多次向前推(推)到同一個控制器,那麼您需要通過創建一個指向您的控制器的屬性並在推入該控制器之前檢查該控制器是否存在來執行代碼。

0

正如其他人指出的那樣,您不能使用segue推送到控制器的現有實例。執行segue的過程總是爲您創建一個新的實例作爲目標控制器。我個人認爲,當我在視圖控制器的現有實例之間跳轉時,我認爲「容器視圖控制器」(例如UIPageViewController)可以很容易地在兩個或多個控制器之間轉換,而不必每次都重新實例化它們。

如果您不喜歡頁面視圖控制器強加的約束(例如,您可能不喜歡iOS 5版本僅支持頁面捲曲轉換,或者iOS 6只添加滾動轉換,並且您想要別的東西),那麼你會做一個自定義的容器視圖控制器。例如,如果我想在兩個視圖控制器之間跳轉,並且不會每次重新實例化它們,我首先會創建一個自定義容器視圖控制器,即「父級」,並確保我有一個屬性以跟蹤哪個孩子我目前在:

@property (nonatomic) NSInteger childViewIndex; 

如果支持iOS 6。只有0和以上,我會然後添加一個「容器視圖」到我的父視圖控制器的場景。如果以6.0之前支持IOS版本,我會一個標準UIView添加到場景中,然後手動實例化的第一個孩子控制器:

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    UIViewController *controller; 

    // add the first child 

    UIViewController *controller = [self addChildWithIdentifier:@"One"]; 
    [self.containerView addSubview:controller.view]; 
    [controller didMoveToParentViewController:self]; 
    self.childViewIndex = 0; 
} 

- (UIViewController *)addChildWithIdentifier:(NSString *)storyboardIdentifier 
{ 
    UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:storyboardIdentifier]; 
    [self addChildViewController:controller]; 
    controller.view.frame = self.containerView.bounds; 
    controller.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

    return controller; 
} 

然後,當我想過渡到第二個孩子(或過渡回第一個孩子),我會打電話給父視圖控制器中執行以下程序:

- (void)transitionToViewControllerIndex:(NSInteger)index 
{ 
    // don't do anything if we're trying to transition to ourselves! 

    if (index == self.childViewIndex) 
     return; 

    // identify the two controllers in question 

    UIViewController *sourceController = self.childViewControllers[self.childViewIndex]; 
    UIViewController *destinationController; 

    // if we're asking for page 2, but we only have one defined, then we'll have to instantiate it 

    BOOL instantiateDestination = (index == 1 && [self.childViewControllers count] < 2); 

    if (instantiateDestination) 
     destinationController = [self addChildWithIdentifier:@"Two"]; 
    else 
     destinationController = self.childViewControllers[index]; 

    // configure the destination controller's frame 

    destinationController.view.frame = sourceController.view.frame; 

    // if you're jumping back and forth, set the animation appropriate for the 
    // direction we're going 

    UIViewAnimationOptions options; 

    if (index > self.childViewIndex) 
    { 
     options = UIViewAnimationOptionTransitionFlipFromRight; 
    } 
    else 
    { 
     options = UIViewAnimationOptionTransitionFlipFromLeft; 
    } 

    // now transition to that destination controller 

    [self transitionFromViewController:sourceController 
         toViewController:destinationController 
           duration:0.5 
           options:options 
          animations:^{ 
           // for simple flip, you don't need anything here, 
           // but docs say this can't be NULL; if you wanted 
           // to do some other, custom annotation, you'd do it here 
          } 
          completion:^(BOOL finished) { 
           if (instantiateDestination) 
            [destinationController didMoveToParentViewController:self]; 
          }]; 

    self.childViewIndex = index; 
} 

因此,過渡到第二子視圖控制器,你可以直接電話諮詢:

[self transitionToViewControllerIndex:1]; 

如果你想轉換回,你可以撥打:

[self transitionToViewControllerIndex:0]; 

我只在這裏劃傷表面,但容器視圖控制器(或者如果沒有通用的標準爲你做的工作,一個自定義的容器視圖控制器)正是你需要的。

欲瞭解更多信息,請參見:

相關問題