iOS UIButton连续点击

开发过程中,总是遇到按钮连续点击后,多次触发事件,导致程序奔溃或者体验差,需要我们禁止按钮的连续点击事件,当然我们可以使用属性userInteractionEnabled来设置是否支持交互.点击后设置为NO,事件处理完毕后设置为YES,这样是可以满足需求的.当然还可使用performSelector:withObject:afterDelay:和cancelPreviousPerformRequestsWithTarget两个方法,同样也可达到效果!
不多说什么,我们主要说说Runtime方式解决这个问题的方法!上代码:
我们创建UIButton的一个分类,这样就可以为所有的按钮添加

  • UIButton+touchInterval.h

      #import <UIKit/UIKit.h>
      #define defaultInterval .7// 默认间隔时间
      @interface UIButton (touchInterval)
      /**
      *  设置点击时间间隔
      */
      @property (nonatomic, assign) NSTimeInterval timeInterVal;
      @end
    
  • UIButton+touchInterval.m

      #import "UIButton+touchInterval.h"
      #import <objc/runtime.h>
    
      @interface UIButton ()
      /**
      *  BOOL 设置是否执行触及事件方法
      */
      @property (nonatomic, assign) BOOL isExecuteEvent;
    
      @end
      
      @implementation UIButton (touch)
    
      + (void)load {
      	static dispatch_once_t onceToken;
      	dispatch_once(&onceToken, ^{
      		//方法选择器
      		SEL oldSel = @selector(sendAction:to:forEvent:);
      		SEL newSel = @selector(wm_sendAction:to:forEvent:);
      		// 获取到响应者链事件分发方法
      		Method oldMethod = class_getInstanceMethod(self, oldSel);
      		// 获取到上面新建的newsel方法
      		Method newMethod = class_getInstanceMethod(self, newSel);
      		// IMP 指方法实现的指针,每个方法都有一个对应的IMP,
      		//调用方法的IMP指针避免方法调用出现死循环问题
      
      		BOOL isAdd = class_addMethod(self, oldSel, method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
      		if (isAdd) {
          		// 将newSel替换成oldMethod
          		class_replaceMethod(self, newSel, method_getImplementation(oldMethod), method_getTypeEncoding(oldMethod));
      		}else{
          		// 给两个方法互换实现
          		method_exchangeImplementations(oldMethod, newMethod);
      		}
      	});
      }
    
      - (void)wm_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
      	if ([NSStringFromClass(self.class) isEqualToString:@"UIButton"]) {
      		if (!self.isExecuteEvent) {
          		//设置点击间隔时间,如果未设置,默认为defaultInterval=0.7
          		self.timeInterVal = (self.timeInterVal == 0? defaultInterval:self.timeInterVal);
      		}
      		if (self.isExecuteEvent) {
          		//如果是YES,则不发送事件消息
          		return;
      		}
      		if (self.timeInterVal > 0) {
          		//在设置的时间内isExecuteEvent为YES
          		self.isExecuteEvent = YES;
          		//在设置的间隔时间后重新设置isExecuteEvent为NO
          		[self performSelector:@selector(setIsExecuteEvent:) withObject:nil afterDelay:self.timeInterVal];
      		}
      	}
      	//在时间间隔内,isExecuteEvent为YES,不会调用此方法
      	[self wm_sendAction:action to:target forEvent:event];
      }
    
      static const char *UIButton_timeInterValKey = "UIButton_timeInterVal";
      - (NSTimeInterval)timeInterVal {
      	// 动态获取关联对象
      	return [objc_getAssociatedObject(self, UIButton_timeInterValKey) doubleValue];
      }
    
      - (void)setTimeInterVal:(NSTimeInterval)timeInterVal {
      	// 动态设置关联对象
      	objc_setAssociatedObject(self, UIButton_timeInterValKey, @(timeInterVal), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
      }
    
      static const char *UIButton_isExecuteEventKey = "UIButton_isExecuteEvent";
      - (void)setIsExecuteEvent:(BOOL)isExecuteEvent {
      	// 动态设置关联对象
      	objc_setAssociatedObject(self, UIButton_isExecuteEventKey,@(isExecuteEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
      }
    
      - (BOOL)isExecuteEvent {
      	// 动态获取关联对象
      	return [objc_getAssociatedObject(self, UIButton_isExecuteEventKey) boolValue];
      }
      @end
    

我们使用时,只需要设置我们想要的时间间隔即可,如果不设置时间间隔,那么默认间隔时间为defaultInterval = 0.7

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值