1. 程式人生 > 程式設計 >iOS如何獲取最頂層ViewController詳解

iOS如何獲取最頂層ViewController詳解

1 獲取當前螢幕顯示的 Viewcontroller

//獲取當前螢幕顯示的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 {
  // 根檢視為非導航類 
  currentVC = rootVC;
 }
 
 return currentVC;
}

2 分析

2.1 UIApplication 的簡析

UIApplication的核心作用是提供了iOS程式執行期間的控制和協作工作,每一個程式在執行期必須有且僅有一個UIApplication(或則其子類)的一個例項,在程式啟動執行時,會在 main 函式中建立一個 UIApplication的單例例項,在程式碼中可以通過呼叫[UIApplication sharedApplication]來得到這個單例例項的指標。

2.2 KeyWindow 的簡析

在簡析 KeyWindow 前我們先來看一看 UIWindow 的概念

UIWindow 是 UIView 的子類,其在 UIView 添加了一些檢視層級,管理檢視,轉發 UIEvent 物件的屬性和 Method 等等

在上述例項中,我們通過 [UIApplication sharedApplication] 來獲取的 UIApplication 的單例例項物件,然後通過例項物件的 keyWindow再獲取到當前活躍的window(或者說是當前顯示的主視窗).

KeyWindow 即指在IOS開發中活躍視窗,即能接到鍵盤和非觸控事件的一個視窗,一次只能有一個KeyWindow,在IOS 開發中,我們可以通過設定UIWindowLevel的數值來設定最前端的視窗為哪個,Level數值越高的視窗越靠前,如果兩個視窗的Level等級相同,則我們可以通過makeKeyAndVisible來顯示KeyWindow

(void)makeKeyWindow;//讓當前UIWindow變成keyWindow(主視窗)

(void)makeKeyAndVisible;//讓當前UIWindow變成keyWindow,並顯示出來
[UIApplication sharedApplication].windows //獲取當前應用的所有的UIWindow
[UIApplication sharedApplication].keyWindow //獲取當前應用的主視窗
view.window ///獲得某個UIView所在的UIWindow

makeKeyAndVisible 與 makeKeyWindow

  • makeKeyWindow: 只做了一件事就是使當前視窗成為主要視窗。 當前視窗不一定顯示出來
  • makeKeyAndVisible : 做了兩件事使當前視窗成為主要視窗並顯示當前視窗。如果只想顯示的話,我們還可以通過設定其屬性hidden為 NO 即可。=

becomeKeyWindow 與 resignKeyWindow

  • becomeKeyWindow: 程式自動呼叫,用來通知其他視窗 當前容器已被設定為主視窗。 我們不要主動呼叫此方法,此方法是系統自動呼叫的來發通知的,此方法的預設實現不執行任何操作,但子類可以覆蓋它並使用它來執行與成為關鍵視窗相關的任務。
  • resignKeyWindow: 類似becomeKeyWindow,其是呼叫以通知視窗它將要登出掉主鍵視窗的身份.同樣的切勿直接呼叫此方法。

2.3 rootViewController屬性

顧名思義:當前視窗的根檢視

目前只有UIWindow有rootViewController這個屬性,不要跟UINavigationController裡面的根檢視概念混淆。
UINavigationController其實並沒有 rootViewController這個屬性!也就沒有自帶的setter方法。要設定其根檢視只能通過如下方法

- (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 出現生成了一個新的window,加在了介面上面,所以keyWindow就會變成UIAlertControllerShimPresenterWindow這個類

2.4 PresentedViewController 簡析

在 ios 開發中,一般頁面的組成有 NavigationController 或者 其他的 UiViewController、UITabViewController 等等,

  • 在有NavigationController導航欄的話,使用[self.navigationColler pushViewController:animated:] 進入到下一個檢視 ,使用[self.navigationController popViewControllerAnimated:] 返回到上一檢視。
  • 在沒有NavigationController導航欄的時候,使用[self presentViewController:animated:completion:] 進入到下一個檢視,使用 [self dismissViewControllerAnimated:completion:];返回到上一個檢視中。

presentedViewController 與 presentingViewController

案例說明 A.presentedViewController A控制器跳轉到B控制器;B.presentingViewController 就是返回到A控制器。

總結

到此這篇關於iOS如何獲取最頂層ViewController的文章就介紹到這了,更多相關iOS獲取最頂層ViewController內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!