0

我想创建一个自定义 segue,其行为方式与在 UINavigationController 视图控制器上使用时的标准推送 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 表达式)。我可以毫无问题地实例化备用视图控制器,但我想做的是来回走动,而无需每次都重新加载视图控制器(使用后退和下一个按钮)。有没有办法从情节提要中检索现有实例,或者一些标准的方法?

4

3 回答 3

2

而不是使用它的自定义segue,perform做你描述的方式,即实时选择是否推送destaltDest,要么是(1)根本不使用segue,而是pushViewController像你在这里做的那样直接调用,或者(2 ) 准备两个从整个视图控制器发出的 segues,然后调用performSegueWithIdentifier:说我们应该执行哪个。

至于直接从destto ,您可以在导航控制器的视图控制器堆栈上推送然后从堆栈中altDest删除。altDestdestdest

就像关于 iOS 的很多事情一样,如果你根本不使用故事板,这一切都会变得更容易和更明显。这就是我不喜欢故事板的原因:它们头脑简单且局限,而且会分散人们对 iOS实际工作方式的注意力。

于 2013-04-27T16:13:23.667 回答
0

没有办法从情节提要中检索现有的控制器——如果有一个 controllerWithIdentifier: 方法来做到这一点,那就太好了,但没有。Segues(除了展开)总是实例化新的控制器,所以我认为你不能用 segue 做你想做的事。如果您想多次前进(推送)到同一个控制器,那么您需要在代码中创建一个指向您的控制器的属性,并在推送到它之前检查该控制器是否存在。

于 2013-04-27T16:12:53.273 回答
0

正如其他人指出的那样,您不能使用 segue 推送到控制器的现有实例。执行 segue 的过程总是会为您创建一个目标控制器的新实例。

就个人而言,当我在视图控制器的现有实例之间跳转时,我认为“容器视图控制器”,例如 a 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];

我在这里只是触及表面,但容器视图控制器(或者如果没有标准的控制器为您完成这项工作,自定义容器视图控制器)正是您所需要的。

有关更多信息,请参阅:

于 2013-04-27T18:36:01.930 回答