UIControl扩展
@interface UIControl (RKRepeatClick)
/**
可以重复点击的时间间隔
默认为0 不对按钮重复点击处理
*/
@property (nonatomic,assign) NSTimeInterval timeInterval; //用这个给重复点击加间隔
/**
内部属性用于判断是否忽略替换的点击事件
*/
@property (nonatomic,assign) BOOL isIgnoreEvent;
/**
* 如果想要button响应连续点击,此属性要设置为YES【例如:同时响应按钮的按下和抬起】
*/
@property(nonatomic,assign)BOOL canResponseRepeatClick;
@end
#import "UIControl+RKRepeatClick.h"
#import <objc/runtime.h>
#define defaultInterval 0.5 //默认时间间隔 0.5
@implementation UIControl (RKRepeatClick)
- (NSTimeInterval)timeInterval{
return [objc_getAssociatedObject(self,_cmd)doubleValue];
}
- (void)setTimeInterval:(NSTimeInterval)timeInterval{
objc_setAssociatedObject(self,@selector(timeInterval),@(timeInterval),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent{
objc_setAssociatedObject(self,@selector(isIgnoreEvent),@(isIgnoreEvent),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isIgnoreEvent{
return [objc_getAssociatedObject(self,_cmd)boolValue];
}
- (void)resetState{
[self setIsIgnoreEvent:NO];
}
- (void)setCanResponseRepeatClick:(BOOL)canResponseRepeatClick {
objc_setAssociatedObject(self,@selector(canResponseRepeatClick),@(canResponseRepeatClick),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)canResponseRepeatClick {
return [objc_getAssociatedObject(self,_cmd)boolValue];
}
+ (void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL selA = @selector(sendAction:to:forEvent:);
SEL selB = @selector(mySendAction:to:forEvent:);
Method methodA = class_getInstanceMethod(self, selA);
Method methodB = class_getInstanceMethod(self, selB);
//将methodB的实现添加到系统方法中也就是说将methodA方法指针添加成方法methodB的返回值表示是否添加成功
BOOL isAdd = class_addMethod(self, selA,method_getImplementation(methodB),method_getTypeEncoding(methodB));
//添加成功了说明本类中不存在methodB所以此时必须将方法b的实现指针换成方法A的,否则b方法将没有实现。
if(isAdd) {
class_replaceMethod(self, selB,method_getImplementation(methodA),method_getTypeEncoding(methodA));
}else{
//添加失败了说明本类中有methodB的实现,此时只需要将methodA和methodB的IMP互换一下即可。
method_exchangeImplementations(methodA, methodB);
}
});
}
- (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent*)event{
if([NSStringFromClass(self.class) isEqualToString:@"UIButton"] && !self.canResponseRepeatClick) {
self.timeInterval = self.timeInterval == 0 ? defaultInterval:self.timeInterval;
if(self.isIgnoreEvent){
return;
}else if(self.timeInterval > 0){
[self performSelector:@selector(resetState)withObject:nil afterDelay:self.timeInterval];
}
}
//此处methodA和methodB方法IMP互换了,实际上执行sendAction;所以不会死循环
self.isIgnoreEvent = YES;
[self mySendAction:action to:target forEvent:event];
}
@end
FEATURED TAGS
iOS
OC
C
Xcode
MIMEType
屏幕旋转
Mac
工具
SQLite3
重命名
证书+内购
像素
pch
支付协议税务
APP转让
审核
银行卡格式化
git
描述文件
命令行
沙盒日志
i386
x86_64
控制台log
xcode10&iOS12
正则
textfield
输入限制
Pod
真机支持
封面尺寸
SDWebImage
Ruby
RVM
渐变色
jekyll
水印
富文本
标签
M3U8
动、静态库
异步上传
Url编码解码
AlertController
保活
pod报错
特定UI横竖屏
Launch版本号
ijkplayer
适配
手势
截图
网络和信号
礼物缓存
手绘礼物
UIPickerView
文件权限
键盘和菜单
耗时卡顿
国际化
Paypal
AWSS3
npm、Node
控制台
warning
扩展
防盗链
动画
分析
CallKit
侧滑
重置根控制器
播放器
裁剪
日志
bugly
uniapp
Swift
文字翻转
跨域
WebClip
网络请求
地图导航
ZSH
SPM
Vapor
导航
验证码
杀进程
Ubuntu
Android
JWT
vue
html-js
style-class
ssh
PHP
jks
css
Runtime
tree
uniCloud
圆角
总结