iOS如何獲取最頂層ViewController詳解
1 獲取當(dāng)前屏幕顯示的 Viewcontroller
//獲取當(dāng)前屏幕顯示的viewcontroller - (UIViewController *)getCurrentVC { ///下文中有分析 UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; UIViewController *currentVC = [self getCurrentVCFrom:rootViewController]; return currentVC; } - (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC { UIViewController *currentVC; if ([rootVC presentedViewController]) { // 視圖是被presented出來的 rootVC = [rootVC presentedViewController]; } if ([rootVC isKindOfClass:[UITabBarController class]]) { // 根視圖為UITabBarController currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]]; } else if ([rootVC isKindOfClass:[UINavigationController class]]){ // 根視圖為UINavigationController currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]]; } else { // 根視圖為非導(dǎo)航類 currentVC = rootVC; } return currentVC; }
2 分析
2.1 UIApplication 的簡(jiǎn)析
UIApplication的核心作用是提供了iOS程序運(yùn)行期間的控制和協(xié)作工作,每一個(gè)程序在運(yùn)行期必須有且僅有一個(gè)UIApplication(或則其子類)的一個(gè)實(shí)例,在程序啟動(dòng)運(yùn)行時(shí),會(huì)在 main 函數(shù)中創(chuàng)建一個(gè) UIApplication的單例實(shí)例,在代碼中可以通過調(diào)用[UIApplication sharedApplication]來得到這個(gè)單例實(shí)例的指針。
2.2 KeyWindow 的簡(jiǎn)析
在簡(jiǎn)析 KeyWindow 前我們先來看一看 UIWindow 的概念
UIWindow 是 UIView 的子類,其在 UIView 添加了一些視圖層級(jí),管理視圖,轉(zhuǎn)發(fā) UIEvent 對(duì)象的屬性和 Method 等等
在上述實(shí)例中,我們通過 [UIApplication sharedApplication] 來獲取的 UIApplication 的單例實(shí)例對(duì)象,然后通過實(shí)例對(duì)象的 keyWindow再獲取到當(dāng)前活躍的window(或者說是當(dāng)前顯示的主窗口).
KeyWindow 即指在IOS開發(fā)中活躍窗口,即能接到鍵盤和非觸摸事件的一個(gè)窗口,一次只能有一個(gè)KeyWindow,在IOS 開發(fā)中,我們可以通過設(shè)置UIWindowLevel的數(shù)值來設(shè)置最前端的窗口為哪個(gè),Level數(shù)值越高的窗口越靠前,如果兩個(gè)窗口的Level等級(jí)相同,則我們可以通過makeKeyAndVisible來顯示KeyWindow
(void)makeKeyWindow;//讓當(dāng)前UIWindow變成keyWindow(主窗口)
(void)makeKeyAndVisible;//讓當(dāng)前UIWindow變成keyWindow,并顯示出來
[UIApplication sharedApplication].windows //獲取當(dāng)前應(yīng)用的所有的UIWindow
[UIApplication sharedApplication].keyWindow //獲取當(dāng)前應(yīng)用的主窗口
view.window ///獲得某個(gè)UIView所在的UIWindow
makeKeyAndVisible 與 makeKeyWindow
- makeKeyWindow: 只做了一件事就是使當(dāng)前窗口成為主要窗口。 當(dāng)前窗口不一定顯示出來
- makeKeyAndVisible : 做了兩件事使當(dāng)前窗口成為主要窗口并顯示當(dāng)前窗口。如果只想顯示的話,我們還可以通過設(shè)置其屬性hidden為 NO 即可。=
becomeKeyWindow 與 resignKeyWindow
- becomeKeyWindow: 程序自動(dòng)調(diào)用,用來通知其他窗口 當(dāng)前容器已被設(shè)置為主窗口。 我們不要主動(dòng)調(diào)用此方法, 此方法是系統(tǒng)自動(dòng)調(diào)用的來發(fā)通知的,此方法的默認(rèn)實(shí)現(xiàn)不執(zhí)行任何操作,但子類可以覆蓋它并使用它來執(zhí)行與成為關(guān)鍵窗口相關(guān)的任務(wù)。
- resignKeyWindow: 類似becomeKeyWindow, 其是調(diào)用以通知窗口它將要注銷掉主鍵窗口的身份.同樣的切勿直接調(diào)用此方法。
2.3 rootViewController屬性
顧名思義:當(dāng)前窗口的根視圖
目前只有UIWindow有rootViewController這個(gè)屬性,不要跟UINavigationController里面的根視圖概念混淆。
UINavigationController其實(shí)并沒有 rootViewController這個(gè)屬性!也就沒有自帶的setter方法。要設(shè)置其根視圖只能通過如下方法
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController;
獲取 uiwindow的根視圖
方式一
AppDelegate *app =(AppDelegate *) [UIApplication sharedApplication].delegate; UIViewController *rootViewController1 = appdelegate.window.rootViewController;
方式二
UIWindow *window = [UIApplication sharedApplication].keyWindow; UIViewController *rootViewController2 = window.rootViewController;
需要注意的是:
在方式二中,UIAlertController、UIAlertView、UIActionSheet彈出后,上述這些View 出現(xiàn)生成了一個(gè)新的window,加在了界面上面,所以keyWindow就會(huì)變成UIAlertControllerShimPresenterWindow這個(gè)類
2.4 PresentedViewController 簡(jiǎn)析
在 ios 開發(fā)中,一般頁面的組成有 NavigationController 或者 其他的 UiViewController、UITabViewController 等等,
- 在有NavigationController導(dǎo)航欄的話,使用[self.navigationColler pushViewController:animated:] 進(jìn)入到下一個(gè)視圖 ,使用[self.navigationController popViewControllerAnimated:] 返回到上一視圖。
- 在沒有NavigationController導(dǎo)航欄的時(shí)候,使用[self presentViewController:animated:completion:] 進(jìn)入到下一個(gè)視圖,使用 [self dismissViewControllerAnimated:completion:];返回到上一個(gè)視圖中。
presentedViewController 與 presentingViewController
案例說明 A.presentedViewController A控制器跳轉(zhuǎn)到B控制器;B.presentingViewController 就是返回到A控制器。
總結(jié)
到此這篇關(guān)于iOS如何獲取最頂層ViewController的文章就介紹到這了,更多相關(guān)iOS獲取最頂層ViewController內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
iOS應(yīng)用運(yùn)用設(shè)計(jì)模式中的Strategy策略模式的開發(fā)實(shí)例
這篇文章主要介紹了iOS應(yīng)用開發(fā)中對(duì)設(shè)計(jì)模式中的Strategy策略模式的運(yùn)用,例子采用傳統(tǒng)的Objective-C語言代碼演示,需要的朋友可以參考下2016-03-03iOS開發(fā)UI篇—xib的簡(jiǎn)單使用實(shí)例
本篇文章主要介紹了iOS開發(fā)UI篇—xib的簡(jiǎn)單使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-11-11iOS模仿QQ側(cè)邊欄的實(shí)現(xiàn)方法實(shí)例
項(xiàng)目中要做側(cè)邊欄效果,網(wǎng)上諸多demo,都不是最理想的。最后決定自己來實(shí)現(xiàn)一個(gè),所以下面這篇文章主要給大家介紹了關(guān)于利用iOS模仿QQ側(cè)邊欄的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12iOS 使用Moya網(wǎng)絡(luò)請(qǐng)求的實(shí)現(xiàn)方法
這篇文章主要介紹了iOS 使用Moya網(wǎng)絡(luò)請(qǐng)求的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07IOS self和super詳解實(shí)現(xiàn)原理及區(qū)別
這篇文章主要介紹了iOS self和super詳解實(shí)現(xiàn)原理及區(qū)別的相關(guān)資料,這里不僅說明區(qū)別并介紹實(shí)現(xiàn)原理,具有參考價(jià)值,需要的朋友可以參考下2016-12-12IOS textField限制字節(jié)長(zhǎng)度
這篇文章主要介紹了IOS textField限制字節(jié)長(zhǎng)度的相關(guān)資料,需要的朋友可以參考下2016-02-02IOS開發(fā)教程之put上傳文件的服務(wù)器的配置及實(shí)例分享
IOS開發(fā)給人一種高大上的趕腳,弄的好像你不會(huì)IOS就不是個(gè)合格的程序員一樣,好吧,既然是大趨勢(shì),那我們就來學(xué)習(xí)下吧,今天來看看put上傳文件的服務(wù)器配置及案例2014-06-06