Runtime统计按钮点击次数-2021-02-25-周四

2021-03-02  本文已影响0人  勇往直前888

需要统计按钮的统计数据,怎么实现?
当然现实开发中可以用友盟统计,很方便很强大;
如果用自定义的按钮,那么在一个地方统一写一下,也很方便;
如果用UIButton,自己实现呢?
当然是用runtimecategory来实现。

按钮分类

@interface UIButton (ClickCount)

// 点击次数
@property (assign, nonatomic) NSInteger clickCount;

// 点击响应
@property (copy, nonatomic) void(^currentActionBlock)(void);

@end
// 关联对象的key
static NSString *clickCountKey = @"clickCount";
static NSString *currentActionBlockKey = @"currentActionBlock";
// setter/getter
// 点击次数
- (void)setClickCount:(NSInteger)clickCount {
    objc_setAssociatedObject(self, &clickCountKey, @(clickCount), OBJC_ASSOCIATION_ASSIGN);
}

- (NSInteger)clickCount {
    NSNumber *clickCountValue = objc_getAssociatedObject(self, &clickCountKey);
    return clickCountValue.integerValue;
}

// 点击响应
- (void)setCurrentActionBlock:(void (^)(void))currentActionBlock {
    objc_setAssociatedObject(self, &currentActionBlockKey, currentActionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void (^)(void))currentActionBlock {
    return objc_getAssociatedObject(self, &currentActionBlockKey);
}
+ (void)load {
    // 方法替换;用自定义的点击响应替换系统的点击响应
    // 只能交换一次
    static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            
            SEL origilaSEL = @selector(addTarget: action: forControlEvents:);
            
            SEL hook_SEL = @selector(xw_addTarget: action: forControlEvents:);
            
            //交换方法
            Method origilalMethod = class_getInstanceMethod(self, origilaSEL);
            
            
            Method hook_method = class_getInstanceMethod(self, hook_SEL);
            
            
            class_addMethod(self,
                            origilaSEL,
                            class_getMethodImplementation(self, origilaSEL),
                            method_getTypeEncoding(origilalMethod));
            
            class_addMethod(self,
                            hook_SEL,
                            class_getMethodImplementation(self, hook_SEL),
                            method_getTypeEncoding(hook_method));
            
            method_exchangeImplementations(class_getInstanceMethod(self, origilaSEL), class_getInstanceMethod(self, hook_SEL));
            
        });
}

// 替换的方法,
- (void)xw_addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents {
    
    __weak typeof(target) weakTarget = target;
    __weak typeof(self) weakSelf = self;

    if (action) {
        self.currentActionBlock = ^{
            @try {
                ((void (*)(void *, SEL,  typeof(weakSelf) ))objc_msgSend)((__bridge void *)(weakTarget), action , weakSelf);
            } @catch (NSException *exception) {
            } @finally {
            }
        };
    }
    
    //发送消息 其实是本身  要执行的action 先执行,写下来的 xw_clicked:方法
    [self xw_addTarget:self action:@selector(xw_clicked:) forControlEvents:controlEvents];
}

//拦截了按钮点击后要执行的代码
- (void)xw_clicked:(UIButton *)sender{
    //统计 在这个方法中执行想要操作的
    self.clickCount++;
    
    NSLog(@"%@ 点击 %ld次 ",[sender titleForState:UIControlStateNormal], self.clickCount);
    
    //执行原来要执行的方法
    sender.currentActionBlock();
}

测试界面

image.png

参考文章

iOS统计整个App 每个按钮的点击次数

ClickCountOfButton

Demo地址

RuntimeDemo

上一篇下一篇

猜你喜欢

热点阅读