preface

  • Requirement introduction: most of the time we do not want to button multiple consecutive press, if to write Enabled slightly troublesome, here provides a control button click interval time method, I have encapsulated convenient use

GitHub: KJEmitterView

API

/ * * * * * * * * * * * * * * * * * * * the two mutually exclusive * * * * * * * * * * * * * * * * * * * * / / / / accept the click event time interval @ property (nonatomic, assign) NSTimeInterval kj_AcceptEventTime; @property (nonatomic, assign) NSTimeInterval kj_AcceptDealTime; The /* ****************** properties are mutually exclusive ********************/Copy the code

Runtime method exchange

Internal implementation in the form of a Category, invasive into consideration, so there is no method to exchange on the load, but in the form of commissioned (KJButtonTimeExchangeMethodProtocol), internal adopts dispatch_once way to ensure that only call once

@ protocol KJButtonTimeExchangeMethodProtocol < NSObject > @ required / / / whether the open interval method + exchange (void) kj_openTimeExchangeMethod; @endCopy the code

You can choose to call kj_AcceptEventTime or kj_AcceptDealTime before any property you want to use, such as viewDidLoad

[UIButton kj_openTimeExchangeMethod];
Copy the code

The exchange method sendAction:to:forEvent: determines the interval in kj_sendAction:to:forEvent:

- (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]; }}Copy the code
If you don’t need to click the event interval to handle it, you just need tokj_AcceptEventTimeandkj_AcceptDealTimeBoth attribute values should be set to non-positive

implementation

// // UIButton+KJBlock. M // KJEmitterView // // Created by Yang Kejun on 2019/4/4. // Copyright © 2019 Yang Kejun. All rights reserved. // https://github.com/yangKJ/KJExtensionHandler #import "UIButton+KJBlock.h" #import <objc/runtime.h> @implementation UIButton (KJBlock) static char kParameterTag; /// Add click event, The default UIControlEventTouchUpInside - (void) kj_addAction (KJButtonBlock) block {objc_setAssociatedObject (self, & kParameterTag, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside]; } /// add event - (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]; } /// event response method - (void)action:(UIButton*)sender{KJButtonBlock block = objc_getAssociatedObject(self, &kParameterTag); if (block) block(self); + (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); } @endCopy the code

Rough packaging, hope god help to modify and improve

Note: Some of the functions and Demo used in this article are from the tripartite library **KJEmitterView**, if there is a need for friends can bepod 'KJEmitterView'Introduction to

Button processing is the end of the introduction, there are related to add, writing articles is not easy, please click **Little stars* * portal