美文网首页
iOS Button连按处理防止按钮频繁点击触发

iOS Button连按处理防止按钮频繁点击触发

作者: 弹吉他的少年 | 来源:发表于2019-10-11 09:05 被阅读0次

    前言

    • 需求介绍:很多时候我们不希望按钮多次连按,频繁触发,如果去写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处理介绍就到此完毕,后面有相关再补充,写文章不容易,还请点个小星星传送门

    相关文章

      网友评论

          本文标题:iOS Button连按处理防止按钮频繁点击触发

          本文链接:https://www.haomeiwen.com/subject/zkazpctx.html