[英]Custom segue to push a specific UIViewController to UINavigationController
我想創建一個自定義segue,其作用方式與在UINavigationController視圖控制器上使用時標准push segue相同。 我已經實現了我的自定義segue:
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];
}
正如您所看到的,我想使用自定義推送segue的原因是我可以根據用戶配置決定推送哪個視圖控制器(目前只檢查一個簡單的1 == 2表達式)。 我可以毫無問題地實例化備用視圖控制器,但我希望能夠做的是每次都不來重新加載視圖控制器(使用后退和下一個按鈕)。 有沒有辦法從故事板中檢索現有實例,或者這樣做的一些標准方法?
而不是自定義segue與其perform
,做你所描述的方式,即實時選擇是否推動dest
或altDest
,是(1)根本不使用segues並直接調用pushViewController
,就像你在這里做的一樣,或(2)准備從視圖控制器整體發出的兩個segue,並調用performSegueWithIdentifier:
來說明我們應該執行哪些。
至於直接從dest
到altDest
,你可以在dest
頂部推動altDest
,然后從導航控制器的視圖控制器的堆棧中刪除dest
。
就像關於iOS一樣,如果你根本不使用故事板,這就更容易也更明顯了。 這就是為什么我不喜歡故事板:它們是如此簡單和限制,它們分散了人們對iOS 真正工作方式的注意力。
沒有辦法從故事板中檢索現有的控制器 - 如果有一個controllerWithIdentifier:方法來做這件事會很好,但事實並非如此。 Segues(除了unwinds)總是實例化新的控制器,所以我認為你不能用segue做你想做的事。 如果你想多次前進(推送)到同一個控制器,那么你需要在代碼中通過創建一個指向你的控制器的屬性,並在推送它之前檢查該控制器是否存在來完成它。
正如其他人所指出的那樣,你不能使用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];
我只是在這里表面,但容器視圖控制器(或者如果沒有標准的那些為您完成工作,自定義容器視圖控制器)正是您所需要的。
有關更多信息,請參閱:
在適用於iOS的View Controller編程指南中 創建自定義容器視圖控制器 。
在WWDC 2011會話視頻中 實現UIViewController包含 (需要Apple開發人員ID)。
在UIViewController類參考中 實現Container View Controller 。
適用於iOS的View Controller Catalog中的頁面視圖控制器 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.