iOS 按钮连点问题

在开发过程中应该都遇到这样的问题,当重复点击某个按钮时造成了push多次,造成体验很差,特别是在需要进行网络请求,网速不好时,出现的几率很大。这里主要介绍两种处理方式。

1.点击一次后将button的可交互性变为NO

如果在button的点击事件中要做耗时操作,比如进行网路请求时,可以考虑在点击时将按钮的可交互性变为NO,

btn.userInteractionEnabled = NO

然后在网络请求结束后再将其可交互性变为YES即可。这样可以有效避免按钮重复点击造成的多次puch问题,处理简单,缺点为比较麻烦,每个地方都要写,如果不加注意便会漏掉恢复可交互性。

2.也就是网上最常用的解决方法,使用runtime控制button响应事件的时间间隔,使其规定时间内只响应一次点击事件。

代码如下:

 

button分类的.h文件

 

@interface UIButton (Category)

 

/** 按钮重复点击的时间间隔,以秒为单位 **/

@property NSTimeInterval repeatEventInterval;

@end

 

.m文件

#import <objc/message.h>

// 默认的按钮点击时间间隔

static const NSTimeInterval defaultDuration = 2.0f;

 

const char *repeatEventIntervalKey  = "repeatEventIntervalKey";

const char *previousClickTimeKey      = "previousClickTimeKey";

@implementation UIButton (Category)

+ (void)load {

    

    // 交换方法实现

    Method sendAction = class_getInstanceMethod([self class], @selector(sendAction:to:forEvent:));

    Method xy_SendAction = class_getInstanceMethod([self class], @selector(xy_sendAction:to:forEvent:));

    

    method_exchangeImplementations(sendAction, xy_SendAction);

}

 

// // 重写,为了防止在tabBarController下点击tabBarItem时报错

- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {

    [super sendAction:action to:target forEvent:event];

}

- (void)setRepeatEventInterval:(NSTimeInterval)repeatEventInterval {

    

    objc_setAssociatedObject(self, repeatEventIntervalKey, @(repeatEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

 

- (NSTimeInterval)repeatEventInterval {

    

    NSTimeInterval repeatEventIn = (NSTimeInterval)[objc_getAssociatedObject(self, repeatEventIntervalKey) doubleValue];

    

    // 如果外界设置的重复点击的时间间隔大于0,就按照用户设置的去处理,如果用户设置的间隔时间小于或等于0,就按照无间隔处理

    if (repeatEventIn > 0) {

        return repeatEventIn;

    }else

    {

        return defaultDuration;

    }

    

    return 0.0;

}

 

- (void)setPreviousClickTime:(NSTimeInterval)previousClickTime {

    

    objc_setAssociatedObject(self, previousClickTimeKey, @(previousClickTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

 

 

- (NSTimeInterval)previousClickTime {

    

    NSTimeInterval previousEventTime = [objc_getAssociatedObject(self, previousClickTimeKey) doubleValue];

    if (previousEventTime != 0) {

        

        return previousEventTime;

    }

    

    return 1.0;

}

 

- (void)xy_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {

    

    NSTimeInterval time = [[[NSDate alloc] init] timeIntervalSince1970];

    if (time - self.previousClickTime < self.repeatEventInterval) {

        return;

    }

    

    // 如果间隔时间大于0

    if (self.repeatEventInterval > 0) {

        self.previousClickTime = [[[NSDate alloc] init] timeIntervalSince1970];

    }

    // 已在load中与系统的sendAction:to:forEvent:方法交换方法实现,所以下面调用的还是系统的方法

    [self xy_sendAction:action to:target forEvent:event];

}

 

@end

 

 

 

参考链接:https://www.jianshu.com/p/98367b4d9816

posted @ 2018-11-01 21:40  梅子~  阅读(1164)  评论(0编辑  收藏  举报