最近项目里要加入按钮的点击事件的统计和按钮是否可点击的权限控制,老大说了,不要第三方的埋点统计,要自己实现,好吧,那就自己实现吧!
到底怎样实现,才最好呢!第一个想到的就是hook点击事件,哎,runtime就是这么强大,想了想,确实很简单,先说下我的思路。首先这个肯定有后台的配合,移动端把所有的按钮及页面进行编码,再就是由后台返回每个按钮是否可点击,如{"B0001P0001":"1"},表示B0001P0001编号的按钮可点击。好了,接下来说说我们iOS端是如何实现的吧,不多说了直接上代码
#import <UIKit/UIKit.h>
@interface UIButton (myTM)
@property (nonatomic,copy)NSString *pageNo;
@end
#import "UIButton+myTM.h"
#import <objc/runtime.h>
static NSString *namekey = @"name";
@implementation UIButton (myTM)
- (void)setPageNo:(NSString *)pageNo {
objc_setAssociatedObject(self, &namekey, pageNo, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)pageNo {
return objc_getAssociatedObject(self, &namekey);
}
@end
按上述代码建立一个UIButton的分类,给分类接一个pageNo属性,这样我们就可以根据pageNo知道对应的按钮是否可点击了,在上代码
#import <UIKit/UIKit.h>
@interface UIControl (runtime)
@end
#import "UIControl+runtime.h"
#import <objc/runtime.h>
#import "UIButton+myTM.h"
@implementation UIControl (runtime)
+(void)load {
Method m1 = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
Method m2 = class_getInstanceMethod(self, @selector(mySendAction:to:forEvent:));
method_exchangeImplementations(m1, m2);
}
- (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
if ([self isKindOfClass:[UIButton class]]) {
UIButton *b = (UIButton *)self;
//这里简写了,实际上肯定要根据拿到的pageNo作为key去取对应的value,就可以得到对应的按钮是否可点击了
if ([b.pageNo isEqualToString:@"1"]||!b.pageNo) {
[self mySendAction:action to:target forEvent:event];
//这里还可以加入按钮点击统计事件,这里我就不写了
} else {
NSLog(@"该按钮不可点击");
return;
}
} else {
[self mySendAction:action to:target forEvent:event];
}
}
@end
这样就算基本完成的,剩下就是测试代码了
#import "ViewController.h"
#import "UIButton+myTM.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *image = [[UIButton alloc]initWithFrame:CGRectMake(50, 50, 50, 50)];
[self.view addSubview:image];
image.pageNo = @"1";
[image setBackgroundColor:[UIColor redColor]];
[image addTarget:self action:@selector(add:) forControlEvents:UIControlEventTouchUpInside];
UIButton *image2 = [[UIButton alloc]initWithFrame:CGRectMake(50, 150, 50, 50)];
[self.view addSubview:image2];
image2.pageNo = @"2";
[image2 setBackgroundColor:[UIColor blueColor]];
[image2 addTarget:self action:@selector(add:) forControlEvents:UIControlEventTouchUpInside];
UIButton *image3 = [[UIButton alloc]initWithFrame:CGRectMake(50, 250, 50, 50)];
[self.view addSubview:image3];
[image3 setBackgroundColor:[UIColor blackColor]];
[image3 addTarget:self action:@selector(add:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)add:(UIButton *)btn{
NSLog(@"该按钮可点击");
}
好了,这就算完成了
这里是demo的gitHub地址:https://github.com/lzkevin1234/runtimeToCountAllAction