美文网首页
IOS获取currentViewController方法改进

IOS获取currentViewController方法改进

作者: leonardni | 来源:发表于2017-12-07 14:55 被阅读48次

    文章结构


    1.现有方法
    2.方法改进
    3.注意事项

    一、现有方法


    看下IQKeyboardManager获取keywindow当前控制器的方法:

    可以看到IQKeyboardManager的方式是先获取到最上层控制器,然后再while循环获取UINavgationControllertopViewController.这个循环退出的条件是currentViewController不为UINavgationController 或 currentViewController已经是UINavgationController 的 topViewController时候退出循环。
    可能出现的问题:

    当keywindow的rootviewcontroller 为UITabBarController 时使用该方法将获取
    不到currentViewController
    

    看了下这个分类也存在这个问题
    iOS-Categories (https://github.com/shaojiankui/iOS-Categories)

    二、方法改进


    UIWindow+Hierarchy.h
    #import <UIKit/UIKit.h>
    
    @interface UIWindow (Hierarchy)
    /*!
     @method topMostController
     
     @return Returns the current Top Most ViewController in hierarchy.
     */
    - (UIViewController*) topMostController;
    
    /*!
     @method currentViewController
     
     @return Returns the topViewController in stack of topMostController.
     */
    - (UIViewController*)currentViewController;
    @end
    
    UIWindow+Hierarchy.m
    #import "UIWindow+Hierarchy.h"
    
    @implementation UIWindow (Hierarchy)
    - (UIViewController*) topMostController
    {
        UIViewController *topController = [self rootViewController];
        
        //  Getting topMost ViewController
        while ([topController presentedViewController]) topController = [topController presentedViewController];
        
        //  Returning topMost ViewController
        return topController;
    }
    
    - (UIViewController*)currentViewController;
    {
        UIViewController *currentViewController = [self topMostController];
    //topMostController 为UITabBarController 取出当前的selectedViewController
    //如果currentViewController 满足是UINavigationController 会再走下面的while循环找出最上的控制器
        if ([currentViewController isKindOfClass:[UITabBarController class]]) {
            currentViewController = [(UITabBarController *)currentViewController selectedViewController];
        }
        while ([currentViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)currentViewController topViewController])
            currentViewController = [(UINavigationController*)currentViewController topViewController];
        return currentViewController;
            
    }
    @end
    

    在这里多加一个条件,判断如果是[UITabBarController class]的话,使用currentViewController = [(UITabBarController *)currentViewController selectedViewController];获取当前selected的控制器,UINavigationController的判断逻辑依然放在下面,如果当前选择的控制器为
    UINavigationController,遍历找到topViewController
    使用方法:

    UIViewController *curVc = [UIApplication sharedApplication].keyWindow.WHcurrentViewController;
                    TGGuidHelpViewController *helpVC = [TGGuidHelpViewController new];
                    [curVc.navigationController pushViewController:helpVC animated:YES];
    

    三、注意事项


    在用pod 方式安装pod 'IQKeyboardManager'时,即使在应用的时候没有引用#import "IQKeyboardManager.h" ,用

    UIViewController *curVc = [UIApplication sharedApplication].keyWindow.currentViewController;
    

    也会走"IQUIWindow+Hierarchy.h"的方法。

    image.png

    建议更改自定义 分类的方法。而不是去更改IQUIWindow+Hierarchy.m 的实现方法,防止重新pod后项目出现问题。

    相关文章

      网友评论

          本文标题:IOS获取currentViewController方法改进

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