文章结构
1.现有方法
2.方法改进
3.注意事项
一、现有方法
看下IQKeyboardManager
获取keywindow当前控制器的方法:
可以看到IQKeyboardManager
的方式是先获取到最上层控制器,然后再while循环获取UINavgationController
的topViewController
.这个循环退出的条件是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"的方法。
建议更改自定义 分类的方法。而不是去更改IQUIWindow+Hierarchy.m 的实现方法,防止重新pod后项目出现问题。