iOS常用

iOS 利用runtime实现button在规定时间内响应一次事

2020-07-29  本文已影响0人  邓布利多教授
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIControl (Limit)

@property (nonatomic) NSTimeInterval timeInterval;

@end

NS_ASSUME_NONNULL_END
#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];
上一篇 下一篇

猜你喜欢

热点阅读