首页 > 代码库 > iOS-UIButton防止连续点击(点击抖动)

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机制及其使用场景

 

iOS-UIButton防止连续点击(点击抖动)