一.根控制器
1.布局
首先我们要先构建一个SwitchingViewController的类,该类继承于UIViewController,负责控制两个视图之间的切换。底部是一个Toolbar,点击之后可以在两个视图间来回切换。
在这里,我们为了使得该控件置底,需要添加左、右、下三个约束,如图所示,将这三个方向的距离都设为0,并且点击旁边的三条虚线,即构建了三个约束,完成约束后,即可将控件贴边置底。
2.编写逻辑
在这里,我们有一个BlueViewController和一个YellowViewController,它们均继承于UIViewController,我们将实现它们的切换逻辑。
首先定义一个切换的实现方法:
//移除了即将离开的视图控制器
if (fromVC != nil) {
[fromVC willMoveToParentViewController: nil];
[fromVC.view removeFromSuperview];
[fromVC removeFromParentViewController];
}
//添加了即将到来的视图控制器
if (toVC != nil) {
[self addChildViewController: toVC];
[self.view insertSubview: toVC.view atIndex: 0];
[toVC didMoveToParentViewController: self];
}
逻辑上来说,添加分为三个步骤:
- 首先通知父Controller加入子Controller
- 然后将子Controller的view添加到父Controller的view中
- 最后将子Controller移动到父Controller中
移除也分为三个步骤:
- 首先将子Controller移动到nil中
- 然后将子Controller的view从父view中移除
- 最后将子Controller从父Controller移除
如果想先见到Blue,那么我们就得在viewDidLoad方法初始化:
- 首先加载Blue(用instantiateViewControllerWithIdentifier)
- 然后设置Blue的视图外形(设置frame)
- 最后直接将Blue加入到SwitchingViewController中去(用刚才的方法)。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.blueViewController = [self.storyboard instantiateViewControllerWithIdentifier: @"Blue"];
self.blueViewController.view.frame = self.view.frame;
[self switchViewFromViewController: nil toViewController: self.blueViewController];
}
最后设置一下切换视图的逻辑:
- (IBAction) switchViews:(id)sender {
if (!self.yellowViewController.view.superview) {
if (!self.yellowViewController) {
self.yellowViewController = [self.storyboard instantiateViewControllerWithIdentifier: @"Yellow"];
}
else {
if (!self.blueViewController) {
self.blueViewController = [self.storyboard instantiateViewControllerWithIdentifier: @"Blue"];
}
}
}
//切换视图控制器
[UIView beginAnimations: @"View Flip" context: NULL];
[UIView setAnimationDuration: 0.4];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
if (!self.yellowViewController.view.superview) {
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
forView: self.view
cache: YES];
self.yellowViewController.view.frame = self.view.frame;
[self switchViewFromViewController: self.blueViewController
toViewController: self.yellowViewController];
}
else {
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft
forView: self.view
cache: YES];
self.blueViewController.view.frame = self.view.frame;
[self switchViewFromViewController: self.yellowViewController
toViewController: self.blueViewController];
}
[UIView commitAnimations];
}
其实与刚才的初始化很相似了:
- 首先加载要切换的视图(用instantiateViewControllerWithIdentifier)
- 然后设置视图的外形(设置frame)
- 最后直接将视图加入到SwitchingViewController中去(用刚才的方法)。
在这里说一下动画:
//初始化动画,效果为UIViewAnimationCurveEaseInOut
[UIView beginAnimations: @"View Flip" context: NULL];
[UIView setAnimationDuration: 0.4];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
//设置从右往左
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
forView: self.view
cache: YES];
//设置动画
[UIView commitAnimations];
最后,在清理内存的时候,顺便也把子视图给清除了。
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
if (!self.blueViewController.view.superview)
self.blueViewController = nil;
else
self.yellowViewController = nil;
}
二.子控制器
要新建一个子Controller,则需要拖动一个新的Controller到storyboard里面去。
然后设置Class和Storyboard ID(用于初始化映射的辨识)。
最后再设计相应的按钮点击逻辑,就可以啦!
- (IBAction)blueButtonPressed:(UIButton *)sender {
UIAlertController *controller = [UIAlertController alertControllerWithTitle: @"Blue button is pressed!"
message: @"You pressed blue!"
preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle: @"Yep, I did!"
style: UIAlertActionStyleDefault
handler: nil];
[controller addAction: action];
[self presentViewController: controller
animated: YES
completion: nil];
}
三.遇到的坑
ToolBar点击全局仍然会响应,这个好像是控件的锅啊,没法解决,换成Button吧。。。