在項(xiàng)目開發(fā)過程中,經(jīng)常會(huì)遇到需要更換window根控制器的情況,這里把常用的方式以及可能遇到的情況總結(jié)了一下。
((AppDelegate *)[UIApplication sharedApplication].delegate).window.rootViewController = rootViewController;
這是最根本的方式,大部分開發(fā)者都會(huì)直接選擇這種方式進(jìn)行更換根控制器。但是這樣的直接轉(zhuǎn)換給人一種很生硬的感覺,所以很多人會(huì)選擇添加一些動(dòng)畫來使更換變得友好一點(diǎn)。例如:
RootTabBarController *rootController = [[RootTabBarController alloc] init];
[UIView transitionFromView:currentRootViewController.view
toView:rootController.view
duration:1.0f
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:^(BOOL finished) {
[AppDelegate shareInstance].window.rootViewController = rootController;
}];
這樣添加是沒有問題的,而且在更換控制器時(shí)產(chǎn)生了一個(gè)過渡動(dòng)畫,看著更舒服一點(diǎn),但是這里有一個(gè)小坑,一些開發(fā)者在某個(gè)頁面中想要更換控制器時(shí)喜歡使用self.view來進(jìn)行視圖切換,這個(gè)時(shí)候就很可能出現(xiàn)問題
如果你的根控制器只是一個(gè)UIViewController,那么使用self.view來進(jìn)行視圖切換是沒有問題的,但是如果是一個(gè)UINavigationController或者UITabBarController時(shí),在子控制器中使用self.view來進(jìn)行視圖切換,可能會(huì)導(dǎo)致動(dòng)畫結(jié)束之后出現(xiàn)白屏的現(xiàn)象!
這是因?yàn)槭褂蒙鲜鰟?dòng)畫切換視圖時(shí),是在同一個(gè)父視圖上進(jìn)行切換的,如果在UINavigationController或者UITabBarController的自控制器中使用self.view,它的父視圖將不會(huì)是window,而是UIViewControllerWrapperView,在根控制器切換過之后,之前的控制器銷毀,會(huì)連帶著UIViewControllerWrapperView一塊銷毀,這樣就導(dǎo)致了更換完之后出現(xiàn)白屏,解決方式很簡單,一種是通過上面給出的那中方式,直接取當(dāng)前根控制器的view來進(jìn)行切換,或者是創(chuàng)建一個(gè)中間視圖,以中間視圖來進(jìn)行視圖切換,動(dòng)畫完成之后再更換根控制器。例如:
UIImageView *transitionView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
LoginViewController *loginViewController = [[LoginViewController alloc] init];
// 將loginViewController.view繪制成圖片
transitionView.image = [Tool paintingPictureWithView:loginViewController.view];
[UIView transitionFromView:self.view toView:transitionView duration:1.0f options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
[transitionView removeFromSuperview];
[AppDelegate shareInstance].window.rootViewController = loginViewController;
}];
