iOS-UIButton防止連續點擊(點擊抖動)


UIButton是我們iOS開發中常用的控件,連續/抖動點擊也是用戶使用中常發生的 !項目之后發現網上解決這一體驗問題的資料還是蠻多的,但還是要自己做份筆記,方便下次查閱!

方案一:

- (void)viewDidLoad{
    [super viewDidLoad];
    
    // 1. 創建 btn 並添加點擊事件
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn setFrame:CGRectMake(100, 100, 100, 60)];
    btn.backgroundColor = [UIColor greenColor];
    [btn addTarget:self action:@selector(clickbtn:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
}
// 2. 延時時間設置為 t (此處設置為1.0s) ,所以凡是前后兩次點擊時間間隔不超過1.0s都會被取消
- (void)clickbtn:(UIButton *)btn{
    NSLog(@" %s ",__FUNCTION__);
    [[self class] cancelPreviousPerformRequestsWithTarget:self
                                                 selector:@selector(handleEvent:)
                                                   object:btn];
    [self performSelector:@selector(handleEvent:) withObject:btn afterDelay:1.0];
}

// 3. 點擊事件的處理方法
- (void)handleEvent:(UIButton *)btn{
    
    NSLog(@" %s ",__FUNCTION__);
}

方案二:給 UIButton 添加分類 ,方便項目中所有的 UIButton 實例都可以方便使用!

主要代碼:

// .h 文件
#import <UIKit/UIKit.h>

@interface UIButton (ClickEventTime)

@property (nonatomic,assign) NSTimeInterval custom_acceptEventInterval;

@end
// .m 文件
#import "UIButton+ClickEventTime.h"
#import <objc/runtime.h>

@implementation UIButton (ClickEventTime)

/**
 1. 攔截系統方法
 2. 用自定義的方法替換第一步攔截的系統方法
 3. 在自定義方法里嘗試終止對連續點擊的前面幾次的響應
 */
#pragma mark ----- 攔截系統方法
+(void)load{
    
    SEL sysSEL = @selector(sendAction:to:forEvent:);
    Method systemMethod = class_getInstanceMethod(self, sysSEL);
    
    SEL customSEL = @selector(custom_sendAction:to:forEvent:);
    Method customMethod = class_getInstanceMethod(self, customSEL);

    method_exchangeImplementations(systemMethod, customMethod);
    
}


#pragma mark ----- 用於替換系統方法的自定義方法

- (void)custom_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
    
    // 是否小於設定的時間間隔
    BOOL needSendAction = (NSDate.date.timeIntervalSince1970 - self.custom_acceptEventTime >= self.custom_acceptEventInterval);
    // 更新上一次點擊時間戳
    if (self.custom_acceptEventInterval > 0) {
        self.custom_acceptEventTime = NSDate.date.timeIntervalSince1970;
    }
    
    if (needSendAction) {
        // 兩次點擊的時間間隔小於設定的時間間隔時,才執行響應事件
        [self custom_sendAction:action to:target forEvent:event];
    }else{
        return;
    }

}

- (NSTimeInterval )custom_acceptEventTime{
    
    return [objc_getAssociatedObject(self, "UIControl_acceptEventTime") doubleValue];
}

- (void)setCustom_acceptEventTime:(NSTimeInterval)custom_acceptEventTime{
    
    objc_setAssociatedObject(self, "UIControl_acceptEventTime", @(custom_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}


#pragma mark ------ 關聯

- (NSTimeInterval )custom_acceptEventInterval{
    
    return [objc_getAssociatedObject(self, "UIControl_acceptEventInterval") doubleValue];
}

- (void)setCustom_acceptEventInterval:(NSTimeInterval)custom_acceptEventInterval{
    
    objc_setAssociatedObject(self, "UIControl_acceptEventInterval", @(custom_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

方案二參考資料

NSObject的load和initialize方法

iOS --- 理解Runtime機制及其使用場景

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM