使用 Storyboard、Auto-layout 与否、某种按钮和一系列子视图控制器进行切换
您希望将容器视图添加到您的视图中,并在按下“切换”子视图控制器的按钮时触发适当的 segue 并执行正确的设置工作。
在 Storyboard 中,您只能将一个 Embed Segue 连接到 Container View。因此,您创建了一个中间处理控制器。制作嵌入 segue 并给它一个标识符,例如 EmbededSegueIdentifier。
在您的父视图控制器中,连接按钮或您想要并保留的任何内容都是在准备 segue 中引用您的子视图控制器。一旦父视图控制器加载,segue 就会被触发。
父视图控制器
@property (weak, nonatomic) MyContainerViewController *myContainerViewController;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"EmbeddedSegueIdentifier"]) {
self.myContainerViewController = segue.destinationViewController;
}
}
您应该很容易将按下的按钮委托给您的容器控制器。
容器控制器
下一段代码部分是从几个来源借来的,但关键的变化是使用了自动布局而不是显式框架。没有什么可以阻止您简单地更改[self addConstraintsForViewController:]
. viewController.view.frame = self.view.bounds
在 Storyboard 中,这个 Container View Controller 不再做任何与目标子视图控制器相关的事情。
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%s", __PRETTY_FUNCTION__);
[self performSegueWithIdentifier:@"FirstViewControllerSegue" sender:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destinationViewController = segue.destinationViewController;
if ([self.childViewControllers count] > 0) {
UIViewController *fromViewController = [self.childViewControllers firstObject];
[self swapFromViewController:fromViewController toViewController:destinationViewController];
} else {
[self initializeChildViewController:destinationViewController];
}
}
- (void)initializeChildViewController:(UIViewController *)viewController
{
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[self addConstraintsForViewController:viewController];
[viewController didMoveToParentViewController:self];
}
- (void)swapFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];
[self transitionFromViewController:fromViewController toViewController:toViewController duration:0.2f options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:^(BOOL finished) {
[self addConstraintsForViewController:toViewController];
[fromViewController removeFromParentViewController];
[toViewController didMoveToParentViewController:self];
}];
}
- (void)addConstraintsForViewController:(UIViewController *)viewController
{
UIView *containerView = self.view;
UIView *childView = viewController.view;
[childView setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:childView];
NSDictionary *views = NSDictionaryOfVariableBindings(childView);
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[childView]|"
options:0
metrics:nil
views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[childView]|"
options:0
metrics:nil
views:views]];
}
#pragma mark - Setters
- (void)setSelectedControl:(ViewControllerSelectionType)selectedControl
{
_selectedControl = selectedControl;
switch (self.selectedControl) {
case kFirstViewController:
[self performSegueWithIdentifier:@"FirstViewControllerSegue" sender:nil];
break;
case kSecondViewController:
[self performSegueWithIdentifier:@"SecondViewControllerSegue" sender:nil];
break;
default:
break;
}
}
自定义序列
您需要的最后一件事是一个什么都不做的自定义 segue,使用从容器视图控制器调用的适当的 segue 标识符前往每个目的地。如果您不输入一个空的 perform 方法,应用程序将崩溃。通常你可以在这里做一些自定义的过渡动画。
@implementation SHCDummySegue
@interface SHCDummySegue : UIStoryboardSegue
@end
- (void)perform
{
// This space intentionally left blank
}
@end