美文网首页
防止按钮重复点击 runtime处理

防止按钮重复点击 runtime处理

作者: 每天刷两次牙 | 来源:发表于2017-06-16 11:57 被阅读36次

//  Created by ming on 2017/4/10.//  Copyright © 2017年 wode. All rights reserved.//#import#import#define defaultInter 2//默认时间间隔

@interface UIButton (UIControl_button)

@property (nonatomic,assign)NSTimeInterval timerInterVal;// 用这个重复点击加时间隔

@property (nonatomic,assign)BOOL isSelect; //YES不允许点击 no运行点击

@end

//

//  UIButton+UIControl_button.m

//

//  Created by ming on 2017/4/10.

//  Copyright © 2017年 wode. All rights reserved.

//

/*runTime*/

#import "UIButton+UIControl_button.h"

@implementation UIButton (UIControl_button)

-(NSTimeInterval)timerInterVal

{

return [objc_getAssociatedObject(self, _cmd)doubleValue];

}

-(void)setTimerInterVal:(NSTimeInterval)timerInterVal

{

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

}

//runtime 动态绑定 属性

-(void)setIsSelect:(BOOL)isSelect

{

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

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

}

//get方法

-(BOOL)isSelect

{

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

return [objc_getAssociatedObject(self, _cmd)boolValue];

}

- (void)resetState{

[self setIsSelect:NO];

}

+(void)load

{

//单利

static dispatch_once_t onceToken;

_dispatch_once(&onceToken, ^{

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

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

/*

class_getMethodImplementation(<#__unsafe_unretained Class cls#>, <#SEL name#>) 获取实现方法(IMP实现方法)

class_getClassMethod  :获取类方法

class_getInstanceMethod: 获取对象方法

*/

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 和methodBDE IMP互换一下即可.

method_exchangeImplementations(methodA, methodB);

}

});

NSLog(@"+load方法");

}

//当我们按钮点击执行时间 sendAction 时,将会执行mySendAction

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

{

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

self.timerInterVal = self.timerInterVal==0?defaultInter:self.timerInterVal;

if (self.isSelect) {

return;

}else if (self.timerInterVal>0){

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

}

}

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

self.isSelect = YES;

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

}

相关文章

网友评论

      本文标题:防止按钮重复点击 runtime处理

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