iOS开发:Runtime解决UITapGesture重复点击问题

Posted wuwuFQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发:Runtime解决UITapGesture重复点击问题相关的知识,希望对你有一定的参考价值。

网上很多利用runtime解决UIButton重复点击的文章,因为 UIControl 的子类都有 sendAction:to:forEvent: 事件,可以通过交换事件的IMP解决,但是点击手势的方法是程序员自己定义的,所以这篇文章是利用 runtime动态添加属性的方法来解决这个问题。

  1. 首先创建一个UIView的Category分类 .h文件
#import <UIKit/UIKit.h>

@interface UIView (FQClickEvent)
/// 是否忽略点击
@property (nonatomic, assign) BOOL ignoreEvent;
/// 防止连点
- (void)antiDoubleClick;
@end

  1. .m文件实现
#import "UIView+FQClickEvent.h"
#import <objc/runtime.h>

@implementation UIView (FQClickEvent)

- (void)setIgnoreEvent:(BOOL)ignoreEvent 
    objc_setAssociatedObject(self, @selector(ignoreEvent), @(ignoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);


- (BOOL)ignoreEvent 
    return [objc_getAssociatedObject(self, _cmd) boolValue];


- (void)antiDoubleClick

       self.ignoreEvent = YES;
 	   [self performSelector:@selector(setIgnoreEvent:) withObject:@(NO) afterDelay:0.5];


@end

  1. 具体使用案列
// 点击事件
- (void)didTapView:(UITapGestureRecognizer*)g

    if (!g.view.ignoreEvent) 
       // [self handlerEvent:g.view];
       //...处理你的业务
        [g.view antiDoubleClick];
    


讲解一下思想:我们不能知道每个点击事件的方法名字,只能在业务上自己判断这次的点击事件是否响应,这个BOOL值是我们通过runtime给分类动态添加的,这个ignoreEvent声明了,但是分类不会实现setter和getter方法。

动态添加属性
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
参数一:id object : 给哪个对象添加属性,这里要给自己添加属性,用self。
参数二:void * == id  key : 属性名,根据key获取关联对象的属性的值,在objc_getAssociatedObject中通过次key获得属性的值并返回。
参数三:id value : 关联的值,也就是set方法传入的值给属性去保存。
参数四:objc_AssociationPolicy policy : 策略,属性以什么形式保存。
	--- --- --- --- --- --- --- --- --- ---
	--- --- --- --- --- --- --- --- --- ---
 typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) 
 OBJC_ASSOCIATION_ASSIGN = 0,  // 指定一个弱引用相关联的对象
 OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 指定相关对象的强引用,非原子性
 OBJC_ASSOCIATION_COPY_NONATOMIC = 3,  // 指定相关的对象被复制,非原子性
 OBJC_ASSOCIATION_RETAIN = 01401,  // 指定相关对象的强引用,原子性
 OBJC_ASSOCIATION_COPY = 01403     // 指定相关的对象被复制,原子性   
;

获得属性
objc_getAssociatedObject(id object, const void *key);
参数一:id object : 获取哪个对象里面的关联的属性。
参数二:void * == id  key : 什么属性,与objc_setAssociatedObject中的key相对应,即通过key值取出value。

此时已经成功给UIView添加ignoreEvent属性,并且UIView对象可以通过点语法为属性赋值。

以上是关于iOS开发:Runtime解决UITapGesture重复点击问题的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发:Runtime解决UIButton重复点击问题

iOS开发:Runtime常见方法

iOS开发:Runtime常见方法

iOS开发:Runtime常见方法

iOS开发:认识一下Runtime

iOS开发:认识一下Runtime