iOS 利用runtime实现button在规定时间内响应一次事
2020-07-29 本文已影响0人
邓布利多教授
- .h文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIControl (Limit)
@property (nonatomic) NSTimeInterval timeInterval;
@end
NS_ASSUME_NONNULL_END
- .m文件
#import "UIControl+Limit.h"
#import <objc/runtime.h>
static const char *UIControl_TimeInterval = "UIControl_TimeInterval";
static const char *UIControl_AllowEvent = "UIControl_AllowEvent";
@implementation UIControl (Limit)
#pragma mark - 间隔时间setter
-(void)setTimeInterval:(NSTimeInterval)timeInterval{
objc_setAssociatedObject(self, UIControl_TimeInterval, @(timeInterval), OBJC_ASSOCIATION_COPY_NONATOMIC);
}
#pragma mark - 间隔时间getter
-(NSTimeInterval)timeInterval{
return [objc_getAssociatedObject(self, UIControl_TimeInterval) doubleValue];
}
#pragma mark - 响应事件setter
-(void)setAllowEvent:(BOOL)allowEvent{
objc_setAssociatedObject(self, UIControl_AllowEvent, @(allowEvent), OBJC_ASSOCIATION_COPY_NONATOMIC);
}
#pragma mark - 响应事件getter
-(BOOL)allowEvent{
return [objc_getAssociatedObject(self, UIControl_AllowEvent) boolValue];
}
#pragma mark - 黑魔法
+(void)load{
//获取系统方法
Method method1 = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
//获取自定义方法
Method method2 = class_getInstanceMethod(self, @selector(swizzled_sendAction:to:forEvent:));
//用自定义方法替换系统方法
method_exchangeImplementations(method1, method2);
}
-(void)swizzled_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
//限制状态为YES,不执行后面的操作
if (self.allowEvent) {
return;
}
//限制时间不为0时,修改限制状态
if (self.timeInterval != 0) {
self.allowEvent = YES;
[self performSelector:@selector(allowEventChangeAction) withObject:nil afterDelay:self.timeInterval];
}
[self swizzled_sendAction:action to:target forEvent:event];
}
#pragma mark - 修改限制状态
-(void)allowEventChangeAction{
self.allowEvent = NO;
}
@end
调用
UIButton *buton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
buton.backgroundColor = UIColor.redColor;
buton.timeInterval = 1;//一秒内响应一次
[buton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
buton.center = self.view.center;
[self.view addSubview:buton];