iOS 获取当前正在显示的视图控制器ViewController(最全)
目錄
先插入以下介紹以下本編文章除標題所講知識外,還額外包含的內容有如下:
1、獲取當前顯示的視圖控制器ViewController 2、如何在多次presentViewController后直接返回到指定層 3、presentedViewController 與 presentingViewController 4、如何通過視圖(view)獲取該視圖所在的控制器(viewController)
一、前言:
本來不怎么想寫這篇文章的, 因為這種東西網上隨便搜一大堆。但是還是發現項目中有些同學,沒怎么理解好,直接照搬網上的,殊不知其本身雖處理了大部分情況,卻仍有一些情況是漏掉的。所以就有了下面這篇文章。
二、場景:
在處理 URL Router 跳轉的時候,經常需要得到“當前最上層的視圖控制器”來進行視圖跳轉。
三、注意點:
網上比較多遺漏的場景是:A present B, B present C,在A中查找當前顯示的視圖控制器的情況。
四、直接快速使用方法:
使用方法很簡單: ①、Podfile添加pod 'CJBaseHelper/UIViewControllerCJHelper',并pod update或pod install ②、庫引入成功后,直接使用如下方法即可。即:
UIViewController *vc = [UIViewControllerCJHelper findCurrentShowingViewController]; 或 UIViewController *vc = [UIViewControllerCJHelper findCurrentShowingViewControllerFrom:self]; 復制代碼至此,恭喜你大功告成!!!
如果您還不清楚,可詳細查看以下說明。如果已清楚及不想了解原理,請跳至六查看其他內容
詳細的使用方法及原理介紹如下:
1、查看開源庫CJBaseHelper內容,可略過
獲取方法已整理到開源庫CJBaseHelper中的UIViewControllerCJHelper。該開源庫內容,可通過pod search CJBaseHelper查看,查看結果如下:
如果你在終端執行pod search CJBaseHelper,未得到上面的結果,是因為cocoaPods的本地search_index.json文件有問題, 方法①:請前往~/Library/Caches/CocoaPods/search_index.json將該文件刪除, 方法②:或者直接在終端輸入:rm ~/Library/Caches/CocoaPods/search_index.json, 刪除后,再重新執行命令即可。2、Podfile添加pod 'CJBaseHelper/UIViewControllerCJHelper'后,執行pod install即可使用該庫中的UIViewControllerCJHelper,即。
platform :ios, '8.0' inhibit_all_warnings!target 'CJDemo' dopod 'CJBaseHelper', :subspecs => ['UIViewControllerCJHelper'] endtarget 'CJDemoTests' doend 復制代碼即通過調用以下兩個方法中的任意一個即可獲取到當前顯示的視圖控制器。
///獲取Window當前顯示的視圖控制器ViewController + (UIViewController *)findCurrentShowingViewController;/*** 獲取Window當前顯示的視圖控制器ViewController** @param vc 從哪個界面開始分析** @return 當前顯示的視圖控制器ViewController*/ + (UIViewController *)findCurrentShowingViewControllerFrom:(UIViewController *)vc; 復制代碼3、實際使用過程
//獲取Window當前顯示的視圖控制器ViewController方法①UIViewController *currentShowViewController1 = [UIViewControllerCJHelper findCurrentShowingViewController];NSLog(@"currentShowViewController1 = %@", NSStringFromClass([currentShowViewController1 class]));//獲取Window當前顯示的視圖控制器ViewController方法②UIViewController *currentShowViewController2 = [UIViewControllerCJHelper findCurrentShowingViewControllerFrom:self];NSLog(@"currentShowViewController2 = %@", NSStringFromClass([currentShowViewController2 class])); 復制代碼五、上述使用的CJBaseHelper/UIViewControllerCJHelper庫的代碼解析
代碼中包括兩種方法,一種是遍歷方法,一種是遞歸方法,兩種方法都能正確查找到當前正在顯示的視圖控制器。廢話不多說,直接上代碼。
+ (UIViewController *)findCurrentShowingViewController {//獲得當前活動窗口的根視圖UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;UIViewController *currentShowingVC = [self findCurrentShowingViewControllerFrom:vc];return currentShowingVC; }//注意考慮幾種特殊情況:①A present B, B present C,參數vc為A時候的情況 /* 完整的描述請參見文件頭部 */ + (UIViewController *)findCurrentShowingViewControllerFrom:(UIViewController *)vc {//方法1:遞歸方法 Recursive methodUIViewController *currentShowingVC;if ([vc presentedViewController]) { //注要優先判斷vc是否有彈出其他視圖,如有則當前顯示的視圖肯定是在那上面// 當前視圖是被presented出來的UIViewController *nextRootVC = [vc presentedViewController];currentShowingVC = [self findCurrentShowingViewControllerFrom:nextRootVC];} else if ([vc isKindOfClass:[UITabBarController class]]) {// 根視圖為UITabBarControllerUIViewController *nextRootVC = [(UITabBarController *)vc selectedViewController];currentShowingVC = [self findCurrentShowingViewControllerFrom:nextRootVC];} else if ([vc isKindOfClass:[UINavigationController class]]){// 根視圖為UINavigationControllerUIViewController *nextRootVC = [(UINavigationController *)vc visibleViewController];currentShowingVC = [self findCurrentShowingViewControllerFrom:nextRootVC];} else {// 根視圖為非導航類currentShowingVC = vc;}return currentShowingVC;/*//方法2:遍歷方法while (1){if (vc.presentedViewController) {vc = vc.presentedViewController;} else if ([vc isKindOfClass:[UITabBarController class]]) {vc = ((UITabBarController*)vc).selectedViewController;} else if ([vc isKindOfClass:[UINavigationController class]]) {vc = ((UINavigationController*)vc).visibleViewController;//} else if (vc.childViewControllers.count > 0) {// //如果是普通控制器,找childViewControllers最后一個// vc = [vc.childViewControllers lastObject];} else {break;}}return vc;//*/ } 復制代碼六、其他補充:
2、如何在多次presentViewController后直接返回到指定層
場景:如果多個控制器都通過 present 的方式跳轉呢?比如從A跳轉到B,從B跳轉到C,從C跳轉到D,如何由D直接返回到A呢?
答:可以通過 presentingViewController 一直找到A控制器,然后調用A控制器的 dismissViewControllerAnimated 方法。方法如下:
UIViewController *controller = self; while(controller.presentingViewController != nil){controller = controller.presentingViewController; } [controller dismissViewControllerAnimated:YES completion:nil]; 復制代碼PS:如果不是想直接返回到A控制器,比如想回到B控制器,while循環的終止條件可以通過控制器的類來判斷。
3、presentedViewController 與 presentingViewController
假設從A控制器通過present的方式跳轉到了B控制器,那么 A.presentedViewController 就是B控制器; B.presentingViewController 就是A控制器。
4、如何通過視圖(view)獲取該視圖所在的控制器(viewController)
+ (nullable UIViewController *)findBelongViewControllerForView:(UIView *)view {UIResponder *responder = view;while ((responder = [responder nextResponder]))if ([responder isKindOfClass: [UIViewController class]]) {return (UIViewController *)responder;}return nil; } 復制代碼結束語:
如欲了解本文中更詳細內容請點擊查看本文中所用開源庫CJBaseHelper中的UIViewControllerCJHelper。
======================================================= 其他更多好用的開源庫歡迎跳轉我的GitHub主頁,歡迎Watch/Star/Follow。
總結
以上是生活随笔為你收集整理的iOS 获取当前正在显示的视图控制器ViewController(最全)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上传和优化Magento 2中的产品图像
- 下一篇: Python 基础常用数据结构