示例界面如下

1s内连续点击“测试点击”按钮几次输出log如下

可以看到只输出了一次
代码如下
#pragma mark - event response
- (void)btnClicked:(id)sender
{
NSLog(@"点击按钮");
}
- (UIButton *)btn
{
if (_btn == nil) {
_btn = [UIButton buttonWithType:UIButtonTypeCustom];
_btn.backgroundColor = [UIColor greenColor];
_btn.dm_acceptEventInterval = 2.0f;
[_btn setTitle:@"测试点击" forState:UIControlStateNormal];
[_btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _btn;
}
按钮设置了一个事件时间间隔
UIControl+Replacement.h 代码如下
#import <UIKit/UIKit.h>
@interface UIControl (Replacement)
// 事件间的时间间隔
@property (nonatomic, assign) NSTimeInterval dm_acceptEventInterval;
@end
UIControl+Replacement.m 代码如下
#import "UIControl+Replacement.h"
#import <objc/runtime.h>
static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";
static const char *UIControl_acceptEventTime = "UIControl_acceptEventTime";
@interface UIControl ()
// 首次事件发生的时间
@property (nonatomic, assign) NSTimeInterval dm_acceptEventTime;
@end
@implementation UIControl (Replacement)
- (NSTimeInterval)dm_acceptEventInterval
{
NSTimeInterval tempAcceptEventInterval = 0.0f;
NSNumber *eventInterval = objc_getAssociatedObject(self, UIControl_acceptEventInterval);
if (eventInterval) {
tempAcceptEventInterval = [eventInterval doubleValue];
}
return tempAcceptEventInterval;
}
- (void)setDm_acceptEventInterval:(NSTimeInterval)dm_acceptEventInterval
{
objc_setAssociatedObject(self, UIControl_acceptEventInterval, [NSNumber numberWithDouble:dm_acceptEventInterval], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSTimeInterval)dm_acceptEventTime
{
NSTimeInterval tempAcceptEventTime = 0.0f;
NSNumber *eventTime = objc_getAssociatedObject(self, UIControl_acceptEventTime);
if (eventTime) {
tempAcceptEventTime = [eventTime doubleValue];
}
return tempAcceptEventTime;
}
- (void)setDm_acceptEventTime:(NSTimeInterval)dm_acceptEventTime
{
objc_setAssociatedObject(self, UIControl_acceptEventTime, [NSNumber numberWithDouble:dm_acceptEventTime], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)load
{
//获取着两个方法
Method systemMethod = class_getInstanceMethod([self class], @selector(sendAction:to:forEvent:));
Method myMethod = class_getInstanceMethod([self class], @selector(dm_sendAction:to:forEvent:));
if (systemMethod && myMethod && strcmp(method_getTypeEncoding(systemMethod), method_getTypeEncoding(myMethod)) == 0) {
method_exchangeImplementations(systemMethod, myMethod);
}
}
- (void)dm_sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event
{
if (NSDate.date.timeIntervalSince1970 - self.dm_acceptEventTime < self.dm_acceptEventInterval) {
// 当前时间 减去 首次事件发生时间 小于 事件间隔时间
return;
}
// 事件间隔时间大于零
if (self.dm_acceptEventInterval > 0) {
// 设置首次事件时间
self.dm_acceptEventTime = NSDate.date.timeIntervalSince1970;
}
[self dm_sendAction:action to:target forEvent:event];
}
@end
这样我们就可以通过设置事件时间间隔来防止按钮事件的重复点击啦
网友评论