利用OCruntime機制,做按鈕的權(quán)限控制及點擊事件的統(tǒng)計

    最近項目里要加入按鈕的點擊事件的統(tǒng)計和按鈕是否可點擊的權(quán)限控制,老大說了,不要第三方的埋點統(tǒng)計,要自己實現(xiàn),好吧,那就自己實現(xiàn)吧!
   到底怎樣實現(xiàn),才最好呢!第一個想到的就是hook點擊事件,哎,runtime就是這么強大,想了想,確實很簡單,先說下我的思路。首先這個肯定有后臺的配合,移動端把所有的按鈕及頁面進(jìn)行編碼,再就是由后臺返回每個按鈕是否可點擊,如{"B0001P0001":"1"},表示B0001P0001編號的按鈕可點擊。好了,接下來說說我們iOS端是如何實現(xiàn)的吧,不多說了直接上代碼
#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屬性,這樣我們就可以根據(jù)pageNo知道對應(yīng)的按鈕是否可點擊了,在上代碼

#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;
            //這里簡寫了,實際上肯定要根據(jù)拿到的pageNo作為key去取對應(yīng)的value,就可以得到對應(yīng)的按鈕是否可點擊了
            if ([b.pageNo isEqualToString:@"1"]||!b.pageNo) {
                 [self mySendAction:action to:target forEvent:event];
                //這里還可以加入按鈕點擊統(tǒng)計事件,這里我就不寫了
            } 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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容