问题
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?
回答1:
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:

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").

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

References:
For general discussion of containment, see Implementing a View Container Controller in the UIViewController Class Reference.
For some details about the implementation, see Creating Custom Container View Controllers in the View Controller Programming Guide for iOS.
回答2:
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?
回答3:
You can also use view animation to avoid push viewcontrollers.you can give view animation like pushing a VC
来源:https://stackoverflow.com/questions/14125145/ios-best-practices-for-a-one-way-navigation-controller