IOS中多视图应用视图切换
实现目标:
我们的目的是在一个主view中可以显示不同的子view。
思路:
首先我们有一个主view controller,叫做switchViewController.
然后定义两个子vc,分别是blueViewController、yellowViewController.
@property (strong, nonatomic) BlueViewController* blueViewController;
@property (strong, nonatomic) YellowViewController* yellowViewController;
在switchViewController中有一个button,点击button时会切换view controller。
在switchViewController中定义一个方法switchViews:
在switchViews:中可以切换两个子view,如果当前显示的blueView就切换为yellowView,反之亦然。
代码讲解:
判断当前显示的view的方法是,判断任意一个子view的superview是否存在,
if (!self.yellowViewController.view.superview)
原理就是如果一个view的superview存在,则他就是显示的。
如果这个子view的superview存在,在判断这个子view对应的controller是否存在
if (!self.yellowViewController)
如果对应的controller不存在,则实例化一个controller
self.yellowViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"Yellow"];
instantiateViewControllerWithIdentifier:方法中的参数是一个标识字符串,不过这个字符串必须是一个view的storyboard id.如果没有遵守这条规则就会遇到这个异常:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Storyboard (<UIStoryboard: 0x7faf4a591cb0>) doesn't contain a view controller with identifier 'Blues''
在确保当前view controller被实例化之后,我们就可以放心的把另一个view从superview中移除
[self.blueViewController.view removeFromSuperview];
再然后就可以把刚实例化的子视图insert到superrview中了
[self.view insertSubview:self.yellowViewController.view atIndex:0];
NOTE:atIndex要设置为0,是把子视图放在最底层,避免遮住了主视图中的button
程序优化:
当然为了应用启动就默认显示了某一视图,可以在viewDidLoad方法中实例化某一子view controller,然后添加到主视图中。
注意因为应用启动时是第一次添加子视图,所以不需要判断是否存在另一个子视图,而且要添加的视图也必须得实例化的。
为了养成良好的习惯,在我们收到系统的内存警告时,可以释放当前未显示的子视图。
判断当前未显示的子视图和添加时一个道理
1 if (!self.blueViewController.view.superview) { 2 self.blueViewController = nil; 3 } 4 else { 5 self.yellowViewController = nil; 6 }
完整代码:
所以最终的完全代码如下:
1 // 2 // SwitchViewController.m 3 // View Switcher 4 // 5 // Created by oooo0oooo0 on 15/10/10. 6 // Copyright (c) 2015年 oooo0oooo0. All rights reserved. 7 // 8 9 #import "SwitchViewController.h" 10 #import "BlueViewController.h" 11 #import "YellowViewController.h" 12 13 @interface SwitchViewController () 14 15 @property (strong, nonatomic) BlueViewController* blueViewController; 16 @property (strong, nonatomic) YellowViewController* yellowViewController; 17 18 @end 19 20 @implementation SwitchViewController 21 22 - (void)viewDidLoad 23 { 24 [super viewDidLoad]; 25 self.blueViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"Blue"]; 26 [self.view insertSubview:self.blueViewController.view atIndex:0]; 27 } 28 29 - (void)didReceiveMemoryWarning 30 { 31 [super didReceiveMemoryWarning]; 32 if (!self.blueViewController.view.superview) { 33 self.blueViewController = nil; 34 } 35 else { 36 self.yellowViewController = nil; 37 } 38 } 39 40 - (IBAction)switchViews:(id)sender 41 { 42 [UIView beginAnimations:@"view flip" context:NULL]; 43 [UIView setAnimationDuration:0.4]; 44 [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 45 46 if (!self.yellowViewController.view.superview) { 47 if (!self.yellowViewController) { 48 self.yellowViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"Yellow"]; 49 } 50 51 [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES]; 52 53 [self.blueViewController.view removeFromSuperview]; 54 [self.view insertSubview:self.yellowViewController.view atIndex:0]; 55 } 56 else { 57 if (!self.blueViewController) { 58 self.blueViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"Blue"]; 59 } 60 61 [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES]; 62 63 [self.yellowViewController.view removeFromSuperview]; 64 [self.view insertSubview:self.blueViewController.view atIndex:0]; 65 } 66 67 [UIView commitAnimations]; 68 } 69 70 @end