作者:郭楠v | 来源:互联网 | 2023-05-30 09:11
篇首语:本文由编程笔记#小编为大家整理,主要介绍了iOS-UIButton防止连续点击(点击抖动)相关的知识,希望对你有一定的参考价值。 UIButton是我们ios开发中常用的控件,连续/抖动点击也
篇首语:本文由编程笔记#小编为大家整理,主要介绍了iOS-UIButton防止连续点击(点击抖动)相关的知识,希望对你有一定的参考价值。
UIButton是我们ios开发中常用的控件,连续/抖动点击也是用户使用中常发生的 !项目之后发现网上解决这一体验问题的资料还是蛮多的,但还是要自己做份笔记,方便下次查阅!
方案一:
- (void)viewDidLoad{
[super viewDidLoad];
// 1. 创建 btn 并添加点击事件
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(100, 100, 100, 60)];
btn.backgroundColor = [UIColor greenColor];
[btn addTarget:self action:@selector(clickbtn:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
// 2. 延时时间设置为 t (此处设置为1.0s) ,所以凡是前后两次点击时间间隔不超过1.0s都会被取消
- (void)clickbtn:(UIButton *)btn{
NSLog(@" %s ",__FUNCTION__);
[[self class] cancelPreviousPerformRequestsWithTarget:self
selector:@selector(handleEvent:)
object:btn];
[self performSelector:@selector(handleEvent:) withObject:btn afterDelay:1.0];
}
// 3. 点击事件的处理方法
- (void)handleEvent:(UIButton *)btn{
NSLog(@" %s ",__FUNCTION__);
}
方案二:给 UIButton 添加分类 ,方便项目中所有的 UIButton 实例都可以方便使用!
主要代码:
// .h 文件
#import
@interface UIButton (ClickEventTime)
@property (nonatomic,assign) NSTimeInterval custom_acceptEventInterval;
@end
// .m 文件
#import "UIButton+ClickEventTime.h"
#import
@implementation UIButton (ClickEventTime)
/**
1. 拦截系统方法
2. 用自定义的方法替换第一步拦截的系统方法
3. 在自定义方法里尝试终止对连续点击的前面几次的响应
*/
#pragma mark ----- 拦截系统方法
+(void)load{
SEL sysSEL = @selector(sendAction:to:forEvent:);
Method systemMethod = class_getInstanceMethod(self, sysSEL);
SEL customSEL = @selector(custom_sendAction:to:forEvent:);
Method customMethod = class_getInstanceMethod(self, customSEL);
method_exchangeImplementations(systemMethod, customMethod);
}
#pragma mark ----- 用于替换系统方法的自定义方法
- (void)custom_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
// 是否小于设定的时间间隔
BOOL needSendAction = (NSDate.date.timeIntervalSince1970 - self.custom_acceptEventTime >= self.custom_acceptEventInterval);
// 更新上一次点击时间戳
if (self.custom_acceptEventInterval > 0) {
self.custom_acceptEventTime = NSDate.date.timeIntervalSince1970;
}
if (needSendAction) {
// 两次点击的时间间隔小于设定的时间间隔时,才执行响应事件
[self custom_sendAction:action to:target forEvent:event];
}else{
return;
}
}
- (NSTimeInterval )custom_acceptEventTime{
return [objc_getAssociatedObject(self, "UIControl_acceptEventTime") doubleValue];
}
- (void)setCustom_acceptEventTime:(NSTimeInterval)custom_acceptEventTime{
objc_setAssociatedObject(self, "UIControl_acceptEventTime", @(custom_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark ------ 关联
- (NSTimeInterval )custom_acceptEventInterval{
return [objc_getAssociatedObject(self, "UIControl_acceptEventInterval") doubleValue];
}
- (void)setCustom_acceptEventInterval:(NSTimeInterval)custom_acceptEventInterval{
objc_setAssociatedObject(self, "UIControl_acceptEventInterval", @(custom_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
方案二参考资料
NSObject的load和initialize方法
iOS --- 理解Runtime机制及其使用场景