iOS: Best practices for a “one-way” navigation con

2019-01-28 20:19发布

I'm developing an app which is essentially a sequence of many different tests (for simplicity, think about an SAT test or a Mensa test). Each test is implemented in a different View+View Controller.

Initially I wanted to use Storyboards and UINavigationControllers for managing the sequence of the tests and the transitions between them, but now I'm questioning the validity of this approach. A UINavigationController is a stack while my navigation is one-way only (once you've completed a test you can't go back). Is there a better way to implement the app? Can I still leverage Storyboards somehow?

3条回答
啃猪蹄的小仙女
2楼-- · 2019-01-28 20:43

You can also use view animation to avoid push viewcontrollers.you can give view animation like pushing a VC

查看更多
3楼-- · 2019-01-28 20:49

I'd use a custom container view controller. So to your main scene, add a "container view". If your target is iOS6, then when editing your storyboard there is a special "container view" object that you can now drag onto your custom container view controller's scene:

container view

If iOS 5, then (a) you have to create the first child scene manually; (b) give it a unique storyboard id (in my example, InitialChild, and (c) you manually instantiate that first child controller and add it as a child programmatically. Thus, assuming you have a UIView called containerView in your custom container view controller's scene, you can have a method like:

- (void)addInitialChild
{
    UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:@"InitialChild"];

    [self addChildViewController:child];
    child.view.frame = self.containerView.bounds;
    [self.containerView addSubview:child.view];
    [child didMoveToParentViewController:self];
}

When you want to transition to the next scene, subclass your own UIStoryboardSegue:

In ReplaceSegue.h:

@interface ReplaceSegue : UIStoryboardSegue

@end

In ReplaceSegue.m

@implementation ReplaceSegue

- (void)perform
{
    UIViewController *source = self.sourceViewController;
    UIViewController *destination = self.destinationViewController;
    UIViewController *container = source.parentViewController;

    [container addChildViewController:destination];
    destination.view.frame = source.view.frame;
    [source willMoveToParentViewController:nil];

    [container transitionFromViewController:source
                           toViewController:destination
                                   duration:0.5
                                    options:UIViewAnimationOptionTransitionCrossDissolve
                                 animations:^{
                                 }
                                 completion:^(BOOL finished) {
                                     [source removeFromParentViewController];
                                     [destination didMoveToParentViewController:container];
                                 }];
}
@end

Then, when doing a segue from the first contained scene to the next, specify a "custom" segue, and use this "ReplaceSegue" as the class (just click on the segue to select it and then look at the "Attributes inspector").

enter image description here

The resulting storyboard might look like (note the "{}" designation between the various children):

containment storyboard


References:

查看更多
时光不老,我们不散
4楼-- · 2019-01-28 20:50

Then just load the next view controller and replace current view (in some top-level view or in app window) with the new one. Add animations if you want. What's the problem?

查看更多
登录 后发表回答