zoukankan      html  css  js  c++  java
  • iOS学习——获取当前最顶层的ViewController

    转载自:https://www.cnblogs.com/mukekeheart/p/8399125.html

     在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 实现方法

    方法一:

    - (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;
    }

    使用方法:

    UIViewController *topmostVC = [self topViewController];

    方法二:

     

    //获取当前屏幕显示的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里,可以弄成类别如下:

    #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参考上文两种方法

  • 相关阅读:
    Windows 2003/2008更改远程桌面端口脚本
    如何修改远程桌面连接3389端口
    关于百度地图(离线)使用过程报“Cannot read property 'jb' of undefined ”错误的解决办法
    IIS 错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    IIS 错误:由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。
    IIS7错误:不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault="Deny")......
    Jqgrid pager 关于“local” dataType 动态加载数据分页的研究(没好用的研究结果)
    JQGrid导出Excel文件
    Oracle以15分钟为界,统计一天内各时间段的数据笔数
    ORA-01438: 值大于为此列指定的允许精度
  • 原文地址:https://www.cnblogs.com/sunyaxue/p/10314332.html
Copyright © 2011-2022 走看看