在開發過程中,我們常常會碰到一種情況就是,在一個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