前言
- 需求介绍:很多时候我们不希望按钮多次连按,频繁触发,如果去写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];
}
}
网友评论