美文网首页
防暴力点击Button分类

防暴力点击Button分类

作者: the_road | 来源:发表于2017-07-26 16:30 被阅读0次

    github.com/smileshang/simpleTools.git

    #import <UIKit/UIKit.h>

    #define defaultInterval .5  //默认时间间隔

    @interface UIButton (touch)

    /**设置点击时间间隔*/

    @property (nonatomic, assign) NSTimeInterval timeInterval;

    @end

    #import "UIButton+touch.h"

    @interface UIButton()

    /**bool 类型 YES 不允许点击  NO 允许点击  设置是否执行点UI方法*/

    @property (nonatomic, assign) BOOL isIgnoreEvent;

    @end

    @implementation UIButton (touch)

    + (void)load{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    SEL selA = @selector(sendAction:to:forEvent:);

    SEL selB = @selector(mySendAction:to:forEvent:);

    Method methodA = class_getInstanceMethod(self, selA);

    Method methodB = class_getInstanceMethod(self, selB);

    //将 methodB的实现 添加到系统方法中 也就是说 将 methodA方法指针添加成 方法methodB的  返回值表示是否添加成功

    BOOL isAdd = class_addMethod(self, selA, method_getImplementation(methodB), method_getTypeEncoding(methodB));

    //添加成功了 说明 本类中不存在methodB 所以此时必须将方法b的实现指针换成方法A的,否则 b方法将没有实现。

    if (isAdd) {

    class_replaceMethod(self, selB, method_getImplementation(methodA), method_getTypeEncoding(methodA));

    }else{

    //添加失败了 说明本类中 有methodB的实现,此时只需要将 methodA和methodB的IMP互换一下即可。

    method_exchangeImplementations(methodA, methodB);

    }});}

    - (NSTimeInterval)timeInterval{return [objc_getAssociatedObject(self, _cmd) doubleValue];}

    - (void)setTimeInterval:(NSTimeInterval)timeInterval{objc_setAssociatedObject(self, @selector(timeInterval), @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);}

    //当我们按钮点击事件 sendAction 时  将会执行  mySendAction

    - (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event

    {

    if ([NSStringFromClass(self.class) isEqualToString:@"UIButton"]) {

    self.timeInterval =self.timeInterval ==0 ?defaultInterval:self.timeInterval;

    if (self.isIgnoreEvent){

    return;

    }else if (self.timeInterval > 0){

    [self performSelector:@selector(resetState) withObject:nil afterDelay:self.timeInterval];

    }

    }

    //此处 methodA和methodB方法IMP互换了,实际上执行 sendAction;所以不会死循环

    self.isIgnoreEvent = YES;

    [self mySendAction:action to:target forEvent:event];

    }

    //runtime 动态绑定 属性

    - (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent{

    // 注意BOOL类型 需要用OBJC_ASSOCIATION_RETAIN_NONATOMIC 不要用错,否则set方法会赋值出错

    objc_setAssociatedObject(self, @selector(isIgnoreEvent), @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    }

    - (BOOL)isIgnoreEvent{

    //_cmd == @select(isIgnore); 和set方法里一致

    return [objc_getAssociatedObject(self, _cmd) boolValue];

    }

    - (void)resetState{

    [self setIsIgnoreEvent:NO];

    }

    @end

    相关文章

      网友评论

          本文标题:防暴力点击Button分类

          本文链接:https://www.haomeiwen.com/subject/dzlokxtx.html