解决UIButton重复点击的问题

问题描述

在点击一个UIButton时,需要触发一个事件去执行,但如果多次重复点击一个UIButton,会重复执行该事件,造成不必要的Bug。

解决方案

添加UIButton的Category,添加一个betweenInterval属性,通过该属性设置所需的时间间隔,并重写sendAction:to:forEvent:方法,通过runtime实现该方法自定义,在自定义的方法中判断点击按钮的时间间隔是否符合要求,如果符合则执行一次该方法,如果不符合则什么都不做

代码实现

#import <UIKit/UIKit.h>

@interface UIButton (IVAdd)

/**
 按钮连续点击有效时间间隔 默认值是 0s
 */
@property (nonatomic,assign) NSTimeInterval betweenInterval;

@end

#import "UIButton+IVAdd.h"
#import <objc/runtime.h>

static const void *kLastClickTime = &kLastClickTime;//记录上次点击的时间
static const void *kBetweenInterval = &kBetweenInterval; //记录时间间隔

@implementation UIButton (IVAdd)

+ (void)load{
    //设置默认值
    objc_setAssociatedObject(self, kLastClickTime, @(CFAbsoluteTimeGetCurrent()), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    Method originalMethod = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
    Method swizzleMethod = class_getInstanceMethod(self, @selector(iv_sendAction:to:forEvent:));
    
    class_addMethod(self, @selector(sendAction:to:forEvent:), class_getMethodImplementation(self, @selector(sendAction:to:forEvent:)), method_getTypeEncoding(originalMethod));
    class_addMethod(self,@selector(iv_sendAction:to:forEvent:) , class_getMethodImplementation(self, @selector(iv_sendAction:to:forEvent:)), method_getTypeEncoding(swizzleMethod));
    
    method_exchangeImplementations(originalMethod, swizzleMethod);
}

- (void)setBetweenInterval:(NSTimeInterval)betweenInterval{
    objc_setAssociatedObject(self, kBetweenInterval, @(betweenInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSTimeInterval )betweenInterval{
    NSTimeInterval betweenInterval = [objc_getAssociatedObject(self, kBetweenInterval)doubleValue];
    return MAX(0.0, betweenInterval);
}

- (void)iv_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
    //设置的时间间隔为0,直接处理即可
    if (self.betweenInterval <= 0) {
        [self iv_sendAction:action to:target forEvent:event];
        return;
    }
    CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
    CFAbsoluteTime lastClickTime = [self lastClickTime];
    if ((currentTime - lastClickTime) < self.betweenInterval) {
        //点击时间间隔小于设定的时间间隔 ,什么都不做
        return;
    }
    [self setupLastClickTime];
    [self iv_sendAction:action to:target forEvent:event];
}

- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
    [self sendAction:action to:target forEvent:event];
}

#pragma mark - Private Methods

- (void)setupLastClickTime{
    objc_setAssociatedObject(self, kLastClickTime, @(CFAbsoluteTimeGetCurrent()), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CFAbsoluteTime)lastClickTime{
    return [objc_getAssociatedObject(self, kLastClickTime) doubleValue];
}

@end

复制代码

使用方法

直接设置betweenInterval属性即可。

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    button.frame = CGRectMake(100, 100, 100, 40);
    button.betweenInterval = 2.0;//设置时间间隔为2s
    [self.view addSubview:button];
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值