在運行過程中更改根控制器的方法:(假設:A為當前根控制器,B為要設的根控制器)
方法一:
1. appdelegate.m中
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
A *vc = [[A alloc] init]; // init會執行viewDidLoad viewWillAppear
vc.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
2. A.m中添加設置,比如一個按鈕跳轉到B並在B中設置B為根控制器
事件如下:
- (void)btnClick:(UIButton *)sender {
B *second = [[B alloc] init];
second.view.backgroundColor = [UIColor blueColor];
[self presentViewController:second animated:YES completion:nil];
// [self.view.window insertSubview:second.view aboveSubview:self.view];
}
3. 注意點出來了,如果使用的是presentViewController則在設置B為根控制器的方法就必須在viewDidLoad與viewWillAppear之后進行設置。不然如下
問題出來了:
Attempt to present <SecondViewController: 0x7fad63e0b470> on <ViewController: 0x7fad63d28dd0> whose view is not in the window hierarchy!
個人分析:因為在沒有present之前就已經走過這個方法了,如果在其中設置更改根控制器就會導致A不在window的層級中,無法presentViewController,事后使用會出現許多問題。
如果使用insertSubView便沒有這個問題
4. B中更改根控制器:(建議在控制器已經完全在window上展示再切換window的根控制器)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
AppDelegate *app = [UIApplication sharedApplication].delegate; // 獲取當前app單例
NSLog(@"appdelegate is %@",app);
UIViewController *vc = app.window.rootViewController;
app.window.rootViewController = self;
[vc removeFromParentViewController];
NSLog(@"當前的根控制器為:%@",self.view.window.rootViewController);
}
遺留問題:A控制器已經沒有用處了,怎樣將其銷毀
A.view = nil; // 這樣就會直接去調用A的viewDidUnload 方法,將當前控制器銷毀,並不是立即去調用,而是要花點時間,就像是
方法二:(提供個基本思路,實際情況大家研究下了)
可以創建多個window,在執行完成后可以設置其window為self.window,並讓其成為key window,然后只要想使用的話就只可以將self.window賦值想要展示的window可此時銷毀剛才的window,然后再將[self.window makeKeyandVisible];
