iOS开发 防止button快速点击

/*

**防止button快速点击Method

*/

@interfaceUIButton (touch)

/**设置点击时间间隔,默认0.5S*/

@property(nonatomic,assign)NSTimeIntervaltimeInterval;

/**

*用于设置单个按钮不需要被hook,忽略YES

*/

@property(nonatomic,assign)BOOLisIgnore;

@end

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

@interfaceUIButton()

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

@property(nonatomic,assign)BOOLisIgnoreEvent;

@end

@implementationUIButton (touch)

+ (void)load{

staticdispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

SELselA =@selector(sendAction:to:forEvent:);

SELselB =@selector(mySendAction:to:forEvent:);

MethodmethodA =class_getInstanceMethod(self,selA);

MethodmethodB =class_getInstanceMethod(self, selB);

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

BOOLisAdd =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(self.isIgnore) {

//不需要被hook

[selfmySendAction:actionto:targetforEvent:event];

return;

}

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

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

if(self.isIgnoreEvent){

return;

}elseif(self.timeInterval>0){

[selfperformSelector:@selector(resetState)withObject:nilafterDelay:self.timeInterval];

}

}

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

self.isIgnoreEvent=YES;

[selfmySendAction:actionto:targetforEvent: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)setIsIgnore:(BOOL)isIgnore{

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

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

}

- (BOOL)isIgnore{

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

return[objc_getAssociatedObject(self,_cmd)boolValue];

}

- (void)resetState{

[selfsetIsIgnoreEvent:NO];

}

@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容