cocoa本身的UIViewController提供了一些用來模態展示ViewController的方法,在比較舊的系統上是 presentModalViewController這個接口,在5.0及以后的系統中統一為presentViewController接口。
我們通常可以這么調用:
[self presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>];
但是這么調用以后,被展示的ViewController所對應的view,實際上是被放都了哪里呢,我之前曾有過三種猜測:
1)被加入到了keyWindow中
2) 被加入到了keyWindow的rootViewController.view中
3) 被加入到了self.view中
但最近在項目中有一個非常有意思的發現:
在appdelegate中初始化一個ViewController並賦給keywindow的rootViewController,然后往該 rootViewController.view加入某個UIViewController的view(AVC.view),這時候,理論上這時 rootViwController.view.subviews里面應該包含的僅有一個AVC.view,然后再在這個AVC中 presentViewController一個UIViewController(BVC),這時候,理論上如果BVC.view被加到 rootViewController的話,rootViwController.view.subviews里面應該包含的子view就是 AVC.view,BVC.view。但實際上我們會發現rootViwController.view.subviews里面應該包含的子view僅有 BVC.view,對,在實際的實現中,cocoa是把那個view替換掉了.
后來我又發現了,確實有被presentViewController加入到keywindow中的情況,我猜想cocoa的實現應該是,如果調用 presentViewController的這個UIViewController的view的superView是window的話,那么被 present的這個ViewController的view就會被加到window中,否則被加入到keyWindow的 rootViewController當中.
很蘋果的技術風格.
比如創建一個 UIAlertController時:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"定位失敗" message:@"請檢查您的網絡和定位是否打開" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
}];
[alertController addAction:sureAction];
appdelegate中:
[self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
在其他頁面的時候:
[self presentViewController:alertController animated:YES completion:nil];