IOS获取currentViewController方法改进

2017-12-07  本文已影响48人  leonardni

文章结构


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后项目出现问题。

上一篇下一篇

猜你喜欢

热点阅读