iOS Button連按處理防止按鈕頻繁點擊觸發

前言

  • 需求介紹:很多時候我們不希望按鈕多次連按,頻繁觸發,如果去寫Enabled略顯麻煩,這里提供一種控制按鈕點擊間隔時間的方法,我已封裝方便使用

API

/* ******************這兩個屬性互斥********************/
/// 接受點擊事件的時間間隔
@property (nonatomic, assign) NSTimeInterval kj_AcceptEventTime;
/// 接受點擊事件執行處理之后的時間間隔
@property (nonatomic, assign) NSTimeInterval kj_AcceptDealTime;
/* ******************這兩個屬性互斥********************/

Runtime方法交換

內部以Category的方式實現,常規的基本都是放在load,這里我選擇以委托的方式來處理,也方便選擇是否交換,只需要再最初的地方調用即可

@protocol KJButtonTimeExchangeMethodProtocol <NSObject>
@required
/// 是否開啟時間間隔的方法交換
+ (void)kj_openTimeExchangeMethod;
@end

實現

其實就是交換點擊方法sendAction:to:forEvent:,在kj_sendAction:to:forEvent:當中判斷時間間隔

#pragma mark - 時間相關方法交換
/// 是否開啟時間間隔的方法交換
+ (void)kj_openTimeExchangeMethod{
    SEL originalSelector = @selector(sendAction:to:forEvent:);
    SEL swizzledSelector = @selector(kj_sendAction:to:forEvent:);
    Class clazz = [self class];
    Method originalMethod = class_getInstanceMethod(clazz, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(clazz, swizzledSelector);
    BOOL boo = class_addMethod(clazz, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    if (boo) {
        class_replaceMethod(clazz, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    }else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
- (NSTimeInterval)kj_AcceptEventTime{
    return [objc_getAssociatedObject(self, @selector(kj_AcceptEventTime)) doubleValue];
}
- (void)setKj_AcceptEventTime:(NSTimeInterval)kj_AcceptEventTime{
    objc_setAssociatedObject(self, @selector(kj_AcceptEventTime), @(kj_AcceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSTimeInterval)kj_AcceptDealTime{
    return [objc_getAssociatedObject(self, @selector(kj_AcceptDealTime)) doubleValue];
}
- (void)setKj_AcceptDealTime:(NSTimeInterval)kj_AcceptDealTime{
    objc_setAssociatedObject(self, @selector(kj_AcceptDealTime), @(kj_AcceptDealTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/// 上一次時間
- (NSTimeInterval)kLastTime{
    return [objc_getAssociatedObject(self, @selector(kLastTime)) doubleValue];
}
- (void)setKLastTime:(NSTimeInterval)kLastTime{
    objc_setAssociatedObject(self, @selector(kLastTime), @(kLastTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/// 交換方法后實現
- (void)kj_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
    if (self.kj_AcceptEventTime <= 0 && self.kj_AcceptDealTime <= 0) {
        [self kj_sendAction:action to:target forEvent:event];
        return;
    }
    // 時間間隔判斷
    NSTimeInterval time = self.kj_AcceptEventTime > 0 ? self.kj_AcceptEventTime : self.kj_AcceptDealTime;
    BOOL boo = (NSDate.date.timeIntervalSince1970 - self.kLastTime >= time);
    // 保存上次點擊時間
    if (self.kj_AcceptEventTime > 0) self.kLastTime = NSDate.date.timeIntervalSince1970;
    if (boo) {
        if (self.kj_AcceptDealTime > 0) self.kLastTime = NSDate.date.timeIntervalSince1970;
        [self kj_sendAction:action to:target forEvent:event];
    }
}
備注:本文用到的部分函數方法和Demo,均來自三方庫KJEmitterView,如有需要的朋友可自行pod 'KJEmitterView'引入即可

Button處理介紹就到此完畢,后面有相關再補充,寫文章不容易,還請點個小星星傳送門

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容