前言
在iOS中开放中,我们可能会遇到需要通过代码获取当前显示在屏幕最顶层的ViewController,比如我们需要在最顶层的ViewController上展示一个UIAlertController的时候。本文将介绍如何获取最顶层的ViewController
实现思路
通过最底层的ViewController依次向上寻找,直到找到最顶层的ViewController,也就是从UIApplication的keyWindow的rootViewController开始寻找(如果有多个UIWindow则要考虑UIWindow的选择问题。
在寻找的过程中,要分别考虑当前ViewController是UITabBarController和UINavigationController的情况,同时还要考虑到当前ViewController是否通过presentViewController:animated:completion:
模态展示了其他ViewController。
实现方法
直接上代码
- (UIViewController *)topViewController {
UIViewController *resultVC;
resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
while (resultVC.presentedViewController) {
resultVC = [self _topViewController:resultVC.presentedViewController];
}
return resultVC;
}
- (UIViewController *)_topViewController:(UIViewController *)vc {
if ([vc isKindOfClass:[UINavigationController class]]) {
return [self _topViewController:[(UINavigationController *)vc topViewController]];
} else if ([vc isKindOfClass:[UITabBarController class]]) {
return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
} else {
return vc;
}
}
使用方法
UIViewController *topmostVC = [self topViewController];
本文个人博客地址: http://wty.im/2016/09/26/get-topmost-view-controller/
Github: https://github.com/wty21cn/
网友评论
1.topViewController就是求全局顶视图控制器的方法,却和UINavigationController的同名方法冲突。从而_topViewController中对UINavigationController调用的同名方法不知所谓。虽然这个方法会被UINavigationController的同名方法override但是这个显然不是原意。
2.topViewController完全可以作为类方法,体现全局性和算法的唯一性。
3. _topViewController这个方法等前缀下划线是苹果专用的,很容易和系统方法冲突。
4. _topViewController和topViewController类似,命名没有区分度。
5. _topViewController中的判断和self没有关系,完全可以作为类方法。
1.命名冲突问题,因为我最开始实现是将其作为AppDelegate类的方法,所以不会出现命名冲突。并且确实可以考虑作为类方法
2.前面加下划线的这种命名方法确实不妥
3.UINavigationController的topViewController和UITabBarController的selectedViewController的presentdViewController已经做了考虑,见topViewController方法中的循环,_topViewController:方法如果返回的是如上提到的这两个VC,则topViewController方法的如下循环会处理其presentedViewController
while (resultVC.presentedViewController) {
resultVC = [self _topViewController:resultVC.presentedViewController];
}
7. UITabBarController的selectedViewController的presentedViewController没考虑。
return nil;
可以不加吧