如何获取当前的控制器
我百度了一下,都是从window的根控制器,开始一个个判断,诸如是否含有UINavigationController、UITabBarController。如果是iPad应用还要判断是否含有UISplitViewController。在这之前还得判断控制器的跳转方式。有没有更简单的方式呢
答案肯定是有了。
废话不多说,直接上代码了。
- 创建单例对象来存储全局变量
currentController
#import <Foundation/Foundation.h>
@interface YHGlobleObject : NSObject
@property (nonatomic, weak) UIViewController *currentController;
SingletonH(Instance)
@end
#import "YHGlobleObject.h"
SingletonM(Instance)
@implementation YHGlobleObject
@end
//单例宏(以下代码放在你经常定义宏的.h文件中)
#define SingletonH(name) + (instancetype)shared##name;
#define SingletonM(name) \
static id _instance; \
\
- (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
- (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}\
\
- (id)mutableCopyWithZone:(NSZone *)zone { \
return _instance; \
}
- 使用runtime的swizzleAPI来hook
viewWillAppear:
方法,如果你能保证当前的控制器都是你自己定义的viewController,也可以不用runtime(毕竟runtime方法作用范围广,深。消耗一定的性能的同时,滥用会造成无法预料的结果。)直接将-(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:(BOOL)animated]; YHGloble.currentController = self; }
写在你自己定义的viewController基类的.m中,否则创建以下分类
@implementation UIViewController (YHExtension)
+(void)load{
[self swizzleInstanceMethod:@selector(viewWillAppear:) with:@selector(hook_viewWillAppear:)];
}
-(void)hook_viewWillAppear:(BOOL)animated{
[self hook_viewWillAppear:animated];
YHGloble.currentController = self;
}
+(BOOL)swizzleInstanceMethod:(SEL)originalSel with:(SEL)newSel {
Method originalMethod = class_getInstanceMethod(self, originalSel);
Method newMethod = class_getInstanceMethod(self, newSel);
if (!originalMethod || !newMethod) return NO;
class_addMethod(self,
originalSel,
class_getMethodImplementation(self, originalSel),
method_getTypeEncoding(originalMethod));
class_addMethod(self,
newSel,
class_getMethodImplementation(self, newSel),
method_getTypeEncoding(newMethod));
method_exchangeImplementations(class_getInstanceMethod(self, originalSel),
class_getInstanceMethod(self, newSel));
return YES;
}
@end
使用的时候直接使用[YHGlobleObject sharedInstance].currentController
即可,总结一下:你也可以hookviewDidAppear
,具体情况具体使用。