在开发过程中,我们常常会碰到一种情况就是,在一个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