前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS学习——获取当前最顶层的ViewController

iOS学习——获取当前最顶层的ViewController

作者头像
mukekeheart
发布2018-02-28 16:43:26
6.3K0
发布2018-02-28 16:43:26
举报

  在iOS开发过程中,我们经常性会需要获取当前页面的ViewController,然后利用ViewController进行一些操作,例如在最顶层的ViewController上展示一个UIAlertController,或者在最顶层的ViewController上present另一个ViewController,或者进行其他操作。

1 实现思路

  通过最底层的ViewController依次向上寻找,直到找到最顶层的ViewController,也就是从UIApplication的keyWindow的rootViewController开始寻找(如果有多个UIWindow则要考虑UIWindow的选择问题。

  在寻找的过程中,要分别考虑当前ViewController是UITabBarController和UINavigationController的情况,同时还要考虑到当前ViewController是否通过 presentViewController:animated:completion: 模态展示了其他ViewController。

2 实现方法

方法一:

代码语言:javascript
复制
- (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;
    }
    return nil;
}

使用方法:

代码语言:javascript
复制
UIViewController *topmostVC = [self topViewController];

方法二:

代码语言:javascript
复制
//获取当前屏幕显示的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;
}

解析代码主要使用了递归的思想(哈哈哈,毕业工作半年,发觉第一次写iOS用到递归,突然觉得高大上)。 [UIApplication sharedApplication].keyWindow.rootViewController获取到的是项目的根视图,结合可能用到UITabBarController或者UINavigationController作为导航结构,以及可能present出新的VC,其实如果用storyboard的方式写UI的话就很清晰,类似树的结构,再利用递归找到当前视图。

ps:

  如果是需要push新的视图,就非常简单了。用上面的方法获取到顶层的视图,判断currentVC.navigationController是否为nil。(为nil,则新建UINavigationController,然后再push;否则直接用currentVC.navigationController去push)。

三 扩展

如果用到的场景主要是vc里,可以弄成类别如下:

代码语言:javascript
复制
#import "UIViewController+Helper.h"

@property (nonatomic, strong ,readonly) UIViewController * _Nullable currentVC;

//当前屏幕显示的viewcontroller
-(UIViewController *)currentVC{
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *controller = [self getCurrentVCFrom:rootViewController];
return controller;
}
//getCurrentVCFrom参考上文两种方法
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 实现思路
  • 2 实现方法
    • 方法一:
      • 方法二:
        • 三 扩展
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档