使用Storyboard、自动布局或不使用,以及一个按钮和一系列子视图控制器进行切换
您想将容器视图添加到您的视图中,并在按下“切换”子视图控制器的按钮时触发适当的segue并执行正确的设置工作。
在Storyboard中,您只能将一个嵌入式Segue连接到容器视图。因此,您需要创建一个中间处理控制器。执行嵌入式segue并为其添加标识符,例如EmbededSegueIdentifier。
在父视图控制器中,连接按钮或其他需要的内容,并在prepare 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中,该容器视图控制器仅会执行segue到目标子视图控制器。
- (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,使用从容器视图控制器调用的适当segue标识符前往每个目标。如果不加入一个空的perform方法,应用程序将崩溃。通常,在这里可以进行一些自定义的过渡动画。
@implementation SHCDummySegue
@interface SHCDummySegue : UIStoryboardSegue
@end
- (void)perform
{
}
@end