在项目中我们有时候会点击一个按钮去发送网络请求,但是重复点击的话就会发送多次,我们需要解决重复发送的问题就需要当用户点击完这个按钮之后,隔一段时间在允许用户去点击。
通过查找资料,解决办法如下:
新建一个UIControl的分类:
在.h文件中我们加上俩个属性
@property(nonatomic,assign)NSTimeInterval zxd_acceptEventInterval;// 重复点击间隔时间
@property (nonatomic) BOOL ignoreEvent; //是否忽略这次点击
.m文件中重写get和set方法
//通过关联对象重写get和set方法
- (NSTimeInterval)zxd_acceptEventInterval
{
return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];
}
- (void)setZxd_acceptEventInterval:(NSTimeInterval)uxy_acceptEventInterval
{
objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(uxy_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//现在是否可点的get和set。通过关联对象。
-(void)setIgnoreEvent:(BOOL)ignoreEvent{
objc_setAssociatedObject(self, UIControl_ignoreEvent, @(ignoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(BOOL)ignoreEvent{
return [objc_getAssociatedObject(self, UIControl_ignoreEvent) boolValue];
}
当我们点击按钮,按钮就会发送事件,调用系统的sendAction:to:forEvent:方法,我们可以自己实现这个方法,利用runtime的黑魔法(交换方法实现)
//交换俩个方法的实现
+(void)load{
Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
Method b = class_getInstanceMethod(self, @selector(__zxd_sendAction:to:forEvent:));
//改变两个方法的实现
method_exchangeImplementations(a, b);
}
- (void)__zxd_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
if (self.ignoreEvent) return;
if (self.zxd_acceptEventInterval > 0)
{
self.ignoreEvent = YES;
[self performSelector:@selector(setIgnoreEvent:) withObject:@(NO) afterDelay:self.zxd_acceptEventInterval];
}
//调用系统实现
[self __zxd_sendAction:action to:target forEvent:event];
}