iOS按鈕暴力點(diǎn)擊的便捷解決方案一

解決方案:此方案只能解決連續(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 首先只響應(yīng)第一次點(diǎn)擊事件 原理是這樣的,首先將分類中的自定義的事件的方法和UIControl的方法通過method...
    Crazy2015閱讀 387評(píng)論 0 0
  • When the button Clicked continuously--iOS點(diǎn)擊事件分類1.程序中大量按鈕沒...
    StrivEver閱讀 12,041評(píng)論 55 89
  • 在iOS開發(fā)中經(jīng)常會(huì)涉及到觸摸事件。本想自己總結(jié)一下,但是遇到了這篇文章,感覺總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載。作者:L...
    WQ_UESTC閱讀 6,114評(píng)論 4 26
  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的?困惑于Cell怎么突然不能點(diǎn)擊了?糾結(jié)于如何實(shí)現(xiàn)這個(gè)奇葩響應(yīng)需求?亦或是...
    Lotheve閱讀 57,979評(píng)論 51 603
  • 摩納哥王妃 在那個(gè)人沒來之前,請(qǐng)做自己的女王
    小激靈閱讀 317評(píng)論 0 0