在开发过程中,我们常常会碰到一种情况就是,在一个controller里面,经常要放很多复杂的控制,最常用的就是tar切换。tar切换,原理就是在一个controller里面,显示另一个controller的view。
如果发现:控制器的view还在,但是view上面的数据不显示,极大可能是因为:控制器被提前销毁了
- 一个控制器的view是可以随意调整尺寸和位置的
- 一个控制器的view是可以随意添加到其他view中
- 如果将一个控制器的view,添加到其他view中显示,那么要想办法保证控制器不被销毁
- 原则:只要view在,view所在的控制器必须得在,这样才能保证view内部的数据和业务逻辑正常
简单例子
// // ViewController.m // 控制器tab切换view显示 // // Created by jiangys on 15/10/11. // Copyright © 2015年 Jiangys. All rights reserved. // #import "ViewController.h"#import "OneViewController.h" #import "TwoViewController.h" #import "ThreeViewController.h"@interface ViewController () - (IBAction)vc1; - (IBAction)vc2; - (IBAction)vc3;/** one */ @property (nonatomic, strong) OneViewController *one; /** two */ @property (nonatomic, strong) TwoViewController *two; /** three */ @property (nonatomic, strong) ThreeViewController *three;@end@implementation ViewController- (OneViewController *)one {if (!_one) {self.one = [[OneViewController alloc] init];self.one.view.frame = CGRectMake(10, 70, 300, 300);}return _one; }- (TwoViewController *)two {if (!_two) {self.two = [[TwoViewController alloc] init];self.two.view.frame = CGRectMake(10, 70, 300, 300);}return _two; }- (ThreeViewController *)three {if (!_three) {self.three = [[ThreeViewController alloc] init];self.three.view.frame = CGRectMake(10, 70, 300, 300);}return _three; }- (void)viewDidLoad {[super viewDidLoad];// HestViewController *test = [[TestViewController alloc] init];// test.view.frame = CGRectMake(100, 100, 200, 300);// test.view.backgroundColor = [UIColor redColor];// [self.view addSubview:test.view];// self.test = test;// 如果发现:控制器的view还在,但是view上面的数据不显示,极大可能是因为:控制器被提前销毁了// 1.一个控制器的view是可以随意调整尺寸和位置的// 2.一个控制器的view是可以随意添加到其他view中// 3.如果将一个控制器的view,添加到其他view中显示,那么要想办法保证控制器不被销毁// 4.原则:只要view在,view所在的控制器必须得在,这样才能保证view内部的数据和业务逻辑正常 }- (IBAction)vc1 {[self.two.view removeFromSuperview];[self.three.view removeFromSuperview];[self.view addSubview:self.one.view]; }- (IBAction)vc2 {[self.one.view removeFromSuperview];[self.three.view removeFromSuperview];[self.view addSubview:self.two.view]; }- (IBAction)vc3 {[self.two.view removeFromSuperview];[self.one.view removeFromSuperview];[self.view addSubview:self.three.view]; } @end
效果:
上面的做法确实是可以实现了效果,但却隐藏了很多隐患。比如,self.View 屏幕旋转,并不会通知到子控制器。当然还有很多其它的问题。
解决方案:
- 当控制器的view互为父子关系,那么控制器最好也互为父子关系
- 通过addChildViewController添加一个子控制器,那么这个子控制器就会被放到ChildViewControllers数据中,只要self存在,那么ChildViewControllers数组就会一直存在
修改:
// // ViewController.m // 控制器tab切换view显示 // // Created by jiangys on 15/10/11. // Copyright © 2015年 Jiangys. All rights reserved. // #import "ViewController.h"#import "OneViewController.h" #import "TwoViewController.h" #import "ThreeViewController.h"@interface ViewController () - (IBAction)vc1; - (IBAction)vc2; - (IBAction)vc3;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 当控制器的view互为父子关系,那么控制器最好也互为父子关系OneViewController *one=[[OneViewController alloc] init];one.view.frame = CGRectMake(10, 70, 300, 300);// 通过addChildViewController添加一个子控制器,那么这个子控制器就会被放到ChildViewControllers数据中// 只要self存在,那么ChildViewControllers数组就会一直存在 [self addChildViewController:one];TwoViewController *two=[[TwoViewController alloc] init];two.view.frame = CGRectMake(10, 70, 300, 300);[self addChildViewController:two];ThreeViewController *three=[[ThreeViewController alloc] init];three.view.frame = CGRectMake(10, 70, 300, 300);[self addChildViewController:three];}- (IBAction)vc1 {OneViewController *one = self.childViewControllers[0];TwoViewController *two = self.childViewControllers[1];ThreeViewController *three = self.childViewControllers[2];[two.view removeFromSuperview];[three.view removeFromSuperview];[self.view addSubview:one.view]; }- (IBAction)vc2 {OneViewController *one = self.childViewControllers[0];TwoViewController *two = self.childViewControllers[1];ThreeViewController *three = self.childViewControllers[2];[one.view removeFromSuperview];[three.view removeFromSuperview];[self.view addSubview:two.view]; }- (IBAction)vc3 {OneViewController *one = self.childViewControllers[0];TwoViewController *two = self.childViewControllers[1];ThreeViewController *three = self.childViewControllers[2];[two.view removeFromSuperview];[one.view removeFromSuperview];[self.view addSubview:three.view]; } @end
源码下载:http://pan.baidu.com/s/1pJ5VXV1