美文网首页程序员
如何在系统的任何一个地方拿到目前正在显示的控制器

如何在系统的任何一个地方拿到目前正在显示的控制器

作者: 饭饭男 | 来源:发表于2018-08-21 14:37 被阅读33次
    -(UIViewController *)presentingVC{
      1.获取当前容器(window)
        UIWindow * window = [[UIApplication sharedApplication] keyWindow];
        if (window.windowLevel != UIWindowLevelNormal){
            NSArray *windows = [[UIApplication sharedApplication] windows];
            for(UIWindow * tmpWin in windows){
                if (tmpWin.windowLevel == UIWindowLevelNormal){
                    window = tmpWin;
                    break;
                }
            }
        }
    2.获取容器的根视图
        UIViewController *result = window.rootViewController;
    3.遍历根视图最后一个视图控制
        while (result.presentedViewController) {
            result = result.presentedViewController;
        }
    4对拿到的这个视图控制器做一个类型判断 OK
        if ([result isKindOfClass:[UITabBarController class]]) {
            result = [(UITabBarController *)result selectedViewController];
        }
        if ([result isKindOfClass:[UINavigationController class]]) {
            result = [(UINavigationController *)result topViewController];
        }
        return result;
    }
    

    windowLevel系统定义了三个级别的Level

    UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;
    UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;
    UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar 
    

    windowLevel的定义:

    typedef CGFloat UIWindowLevel NS_TYPED_EXTENSIBLE_ENUM;
    

    其就是系统给CGFloat重新定义了一个名字 ->UIWindowLevel 那么UIWindowLevel肯定就是一个浮点数
    打印测试后发现

    UIWindowLevelNormal==0.00..
    UIWindowLevelAlert==2000.00..
    UIWindowLevelStatusBar==1000.00..
    

    谁的值越大,谁就显示在窗口的最前面,如果两个UIWindowLevel值相等,后来者显示在前者的上层。正常情况下如果不给UIWindowLevel一个负值,那么UIWindowLevelNormal肯定是最小值,也就是显示在窗口的最下层。

    window.rootViewController
    强调一个window.rootViewController方法 window是应用程序的窗口,也就是一个视图控制器的容器,它负责把相关的UIControllerView装载其中显示。那么window就是通过rootViewController来指定一个根控制器,由根控制器负责push(导航控制器)或者present(模态)

    到这里就明白怎么获取当前正在显示的视图 :1.获取当前容器(window)-> 2.获取容器的根视图 -> 3.遍历根视图最后一个视图控制器 ->4对拿到的这个视图控制器做一个类型判断 OK

    presentedViewController和presentingViewController
    

    在模态调用中,会涉及到presented和dismiss方法 A->B (B就是A的presentedViewController,A就是B的presentingViewController) 这就是为什么我们用

    while (result.presentedViewController) {
            result = result.presentedViewController;
        }
    

    遍历的原因,始终去获取当前视图(刚刚开始是rootViewController)的presentedViewController也就是B视图,直到没有B视图为止

    https://blog.csdn.net/zrhloveswallow/article/details/25603589
    https://www.cnblogs.com/wangguimin/p/4645748.html
    https://www.jianshu.com/p/f60471a7d935

    相关文章

      网友评论

        本文标题:如何在系统的任何一个地方拿到目前正在显示的控制器

        本文链接:https://www.haomeiwen.com/subject/xltjiftx.html