解決方案:此方案只能解決連續(xù)點(diǎn)擊的時(shí)候只響應(yīng)第一次點(diǎn)擊事件
使用runtime來對(duì)sendAction:to:forEvent:方法進(jìn)行hook
分析:
UIControl的sendAction:to:forEvent:方法用于處理事件響應(yīng).
如果我們?cè)谠摲椒ǖ膶?shí)現(xiàn)中, 添加針對(duì)點(diǎn)擊事件的時(shí)間間隔相關(guān)的處理代碼, 則能夠做到在指定時(shí)間間隔中防止重復(fù)點(diǎn)擊.
@interface UIButton (MultiClick)
@property (nonatomic, assign) NSTimeInterval cs_acceptEventInterval; // 重復(fù)點(diǎn)擊的間隔
@property (nonatomic, assign) NSTimeInterval cs_acceptEventTime;//事件點(diǎn)擊的時(shí)間
@end
@implementation UIButton (MultiClick)
// 因category不能添加屬性,只能通過關(guān)聯(lián)對(duì)象的方式。
static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";
- (NSTimeInterval)cs_acceptEventInterval {
return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];
}
- (void)setCs_acceptEventInterval:(NSTimeInterval)cs_acceptEventInterval {
objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(cs_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
static const char *UIControl_acceptEventTime = "UIControl_acceptEventTime";
- (NSTimeInterval)cs_acceptEventTime {
return [objc_getAssociatedObject(self, UIControl_acceptEventTime) doubleValue];
}
- (void)setCs_acceptEventTime:(NSTimeInterval)cs_acceptEventTime {
objc_setAssociatedObject(self, UIControl_acceptEventTime, @(cs_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// 在load時(shí)執(zhí)行hook
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(sendAction:to:forEvent:);
SEL swizzledSelector = @selector(cs_sendAction:to:forEvent:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (success) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)cs_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
if ([NSDate date].timeIntervalSince1970 - self.cs_acceptEventTime < self.cs_acceptEventInterval) {
return;
}
if (self.cs_acceptEventInterval > 0) {
self.cs_acceptEventTime = [NSDate date].timeIntervalSince1970;
}
[self cs_sendAction:action to:target forEvent:event];
}
@end
轉(zhuǎn)載:
http://www.lxweimin.com/p/7bca987976bd