解决思路:创建一个UIButton分类,运用runtime机制修改sendAction:to:forEvent:方法
@interface UIButton (AvoidMutiTouch)
@property (nonatomic, assign) NSTimeInterval uxy_acceptEventTime;
@property (nonatomic,assign) BOOL uxy_ignoreEvent;//是否可以多点
@end
#define kUxy_acceptEventInterval 1 //在多少时间范围内可接受下次点击
@implementation UIButton (AvoidMutiTouch)
static const char *UIControl_acceptedEventTime = "UIControl_acceptedEventTime";
static const char *UIControl_ignoreEvent = "UIControl_ignoreEvent";
- (NSTimeInterval)uxy_acceptEventTime
{
return [objc_getAssociatedObject(self, UIControl_acceptedEventTime) doubleValue];
}
- (void)setUxy_acceptEventTime:(NSTimeInterval)uxy_acceptEventTime
{
objc_setAssociatedObject(self, UIControl_acceptedEventTime, @(uxy_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)uxy_ignoreEvent
{
return [objc_getAssociatedObject(self, UIControl_ignoreEvent) boolValue];
}
- (void)setUxy_ignoreEvent:(BOOL)uxy_ignoreEvent
{
objc_setAssociatedObject(self, UIControl_ignoreEvent, @(uxy_ignoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL selA = @selector(sendAction:to:forEvent:);
SEL selB = @selector(uxySendAction:to:forEvent:);
Method methodA = class_getInstanceMethod(self,selA);
Method methodB = class_getInstanceMethod(self, selB);
BOOL isAdd = class_addMethod(self, selA, method_getImplementation(methodB), method_getTypeEncoding(methodB));
if (isAdd) {
class_replaceMethod(self, selB, method_getImplementation(methodA), method_getTypeEncoding(methodA));
}else{
method_exchangeImplementations(methodA, methodB);
}
});
}
- (void)uxySendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
if ([NSStringFromClass(self.class) isEqualToString:@"UIButton"]) {
if(self.uxy_ignoreEvent){
[self uxySendAction:action to:target forEvent:event];
return;
}
if ([NSDate date].timeIntervalSince1970 - self.uxy_acceptEventTime < kUxy_acceptEventInterval) {
return;
}
if (kUxy_acceptEventInterval > 0) {
self.uxy_acceptEventTime = [NSDate date].timeIntervalSince1970;
}
}
[self uxySendAction:action to:target forEvent:event];
}
@end