GitHub地址:KJEmitterViewgit
/* ******************這兩個屬性互斥********************/
/// 接受點擊事件的時間間隔
@property (nonatomic, assign) NSTimeInterval kj_AcceptEventTime;
/// 接受點擊事件執行處理以後的時間間隔
@property (nonatomic, assign) NSTimeInterval kj_AcceptDealTime;
/* ******************這兩個屬性互斥********************/
複製代碼
內部以Category的方式實現,考慮到侵入性問題,因此沒有將方法交換放在load
裏面,而是選擇以委託(KJButtonTimeExchangeMethodProtocol
)的形式,內部採用 dispatch_once
的方式保證只調用一次github
@protocol KJButtonTimeExchangeMethodProtocol <NSObject>
@required
/// 是否開啓時間間隔的方法交換
+ (void)kj_openTimeExchangeMethod;
@end
複製代碼
能夠選擇在任何你要使用屬性kj_AcceptEventTime
或 kj_AcceptDealTime
以前調用便可,例如viewDidLoadmarkdown
[UIButton kj_openTimeExchangeMethod];
複製代碼
其實就是交換方法 sendAction:to:forEvent:
,在 kj_sendAction:to:forEvent:
當中判斷時間間隔ide
/// 交換方法後實現
- (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 = (CFAbsoluteTimeGetCurrent() - self.kLastTime >= time);
if (self.kj_AcceptEventTime > 0) {
self.kLastTime = CFAbsoluteTimeGetCurrent();
}
if (boo) {
if (self.kj_AcceptDealTime > 0) {
self.kLastTime = CFAbsoluteTimeGetCurrent();
}
[self kj_sendAction:action to:target forEvent:event];
}
}
複製代碼
kj_AcceptEventTime
和kj_AcceptDealTime
兩個屬性值設置爲非正數便可//
// UIButton+KJBlock.m
// KJEmitterView
//
// Created by 楊科軍 on 2019/4/4.
// Copyright © 2019 楊科軍. All rights reserved.
// https://github.com/yangKJ/KJExtensionHandler
#import "UIButton+KJBlock.h"
#import <objc/runtime.h>
@implementation UIButton (KJBlock)
static char kParameterTag;
/// 添加點擊事件,默認UIControlEventTouchUpInside
- (void)kj_addAction:(KJButtonBlock)block{
objc_setAssociatedObject(self, &kParameterTag, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
}
/// 添加事件
- (void)kj_addAction:(KJButtonBlock)block forControlEvents:(UIControlEvents)controlEvents{
objc_setAssociatedObject(self, &kParameterTag, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addTarget:self action:@selector(action:) forControlEvents:controlEvents];
}
/// 事件響應方法
- (void)action:(UIButton*)sender{
KJButtonBlock block = objc_getAssociatedObject(self, &kParameterTag);
if (block) block(self);
}
#pragma mark - 時間相關方法交換
/// 是否開啓時間間隔的方法交換
+ (void)kj_openTimeExchangeMethod{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
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);
}
});
}
/// 交換方法後實現
- (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 = (CFAbsoluteTimeGetCurrent() - self.kLastTime >= time);
if (self.kj_AcceptEventTime > 0) {
self.kLastTime = CFAbsoluteTimeGetCurrent();
}
if (boo) {
if (self.kj_AcceptDealTime > 0) {
self.kLastTime = CFAbsoluteTimeGetCurrent();
}
[self kj_sendAction:action to:target forEvent:event];
}
}
- (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);
}
@end
複製代碼
pod 'KJEmitterView'
引入便可