iOS小技巧:用runtime 解决UIButton 重复点击问题
http://www.cocoachina.com/ios/20150911/13260.html
作者:uxyheaven 授权本站转载。
什么是这个问题
我们的按钮是点击一次响应一次, 即使频繁的点击也不会出问题, 可是某些场景下还偏偏就是会出问题.
通常是如何解决
我们通常会在按钮点击的时候设置这个按钮不可点击. 等待0.xS的延时后,在设置回来; 或者在操作结束的时候设置可以点击.
1
2
3
4
5
6
|
- (IBAction)clickBtn1:(UIbutton *)sender { sender.enabled = NO; doSomething sender.enabled = YES; } |
如果涉及到按钮不同状态不同样式的时候, 用enabled不见得够用.还得额外加个变量来记录状态.
1
2
3
4
5
6
7
|
- (IBAction)clickBtn1:(UIbutton *)sender { if (doingSomeThing) return ; doingSomeThing = YES; doSomething doingSomeThing = NO; } |
笔者举的例子是直接在响应事件的周期内直接禁止点击的. 如果想做1秒内禁止重复点击的话,则得用performSelector:withObject:afterDelay:
漂亮的解决是怎样的
有了重复的代码段就是有了一个共性, 就可以抽象出来.
我们可以给按钮添加一个属性重复点击间隔, 通过设置这个属性来控制再次接受点击事件的时间间隔.
1
2
3
4
5
6
7
8
9
10
11
12
|
@interface UIControl (XY) @property (nonatomic, assign) NSTimeInterval uxy_acceptEventInterval; // 可以用这个给重复点击加间隔 @end static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval" ; - (NSTimeInterval)uxy_acceptEventInterval { return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue]; } - (void)setUxy_acceptEventInterval:(NSTimeInterval)uxy_acceptEventInterval { objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(uxy_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } |
在app启动的时候,我们hook 所有的按钮的 event
1
2
3
4
5
6
7
8
|
@implementation UIControl (XY) + (void)load { Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:)); Method b = class_getInstanceMethod(self, @selector(__uxy_sendAction:to:forEvent:)); method_exchangeImplementations(a, b); } @end |
在我们的点击事件里呢,对点击事件做下过滤
1
2
3
4
5
6
7
8
9
10
|
- (void)__uxy_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { if (self.uxy_ignoreEvent) return ; if (self.uxy_acceptEventInterval > 0) { self.uxy_ignoreEvent = YES; [self performSelector:@selector(setUxy_ignoreEvent:) withObject:@(NO) afterDelay:self.uxy_acceptEventInterval]; } [self __uxy_sendAction:action to:target forEvent:event]; } |
实际使用起来就是这个样子
1
2
3
|
UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [tempBtn addTarget:self action:@selector(clickWithInterval:) forControlEvents:UIControlEventTouchUpInside]; tempBtn.uxy_acceptEventInterval = 0.5; |
文章至此就结束了.虽然不推荐大范围用runtime, 但是小范围内使用还是可以解决不少小问题的.
版权声明:本文为博主原创文章,未经博主允许不得转载。
iOS小技巧:用runtime 解决UIButton 重复点击问题的更多相关文章
- iOS小技巧–用runtime 解决UIButton 重复点击问题
什么是这个问题 我们的按钮是点击一次响应一次, 即使频繁的点击也不会出问题, 可是某些场景下还偏偏就是会出问题. 通常是如何解决 我们通常会在按钮点击的时候设置这个按钮不可点击. 等待0.xS的延时后 ...
- iOS小技巧 - 如何使UIView可以绑定点击事件
让我们这次直接进入正题,有时候我们想做以下这种界面: 目前我就想到三种方案: 做一个tableview,然后组织cell的界面如上图所示 做一个button子类,使得button的界面能如上图所示 做 ...
- iOS小技巧总结,绝对有你想要的
原文链接 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIV ...
- iOS 为移动中的UIView(UIButton )添加点击事件
高高兴兴迎接新的产品新需求,满心欢喜的开始工作,结果研究了一下午才发现,是自己想的太简单了,是我太单纯呀. 需求是这样的类似下雪的效果,随机产生一些小雪花,然后每个雪花可以点击到下个页面. 接到需求之 ...
- iOS开发小技巧--利用MJExtension解决数据结构复杂的模型转换
一.开发中难免会遇到,系统返回的数据中字典套集合,集合里面又套一层字典,然后字典里面还有字典或者集合等等的复杂结构的数据...MJExtension轻松搞定这类问题 1.解决方法一: 例:百思项目中帖 ...
- iOS小技巧3
将颜色合成图片 将颜色合成图片 +(UIImage *)imageWithColor:(UIColor *)color { CGRect rect = CGRectMake(0.0f, 0.0f, 1 ...
- iOS小技巧 - 和屏幕等宽的Table分割线
前言 因为本人也是学习iOS才一个多月,在写程序的过程中经常会遇到一些看似应该很简单,但是要解决好却要知道一点小trick的问题. 因此后面会陆续记一些这类问题,一来加深印象,二来也可以做个备忘录. ...
- 总有你需要的之 ios 小技巧 (下)
图片上绘制文字 写一个UIImage的category NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultPara ...
- 你想要的iOS 小技巧总结
UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(, , ...
随机推荐
- web api中允许跨域访问
①添加owin的引用 ②添加owin.Cors的引用 ③在WebApiConfig中添加 config.EnableCors(new EnableCorsAttribute("*" ...
- mybatis学习:mybatis注解开发一对一的查询配置
实体类: public class Account { private Integer id; private Integer uid; private Double money; private U ...
- JAVA面试常见问题之Redis篇
Redis为单线程 1.Redis 有哪些数据类型 String 哈希 list set 有序set 2.Redis 内部结构 参考:https://www.cnblogs.com/chenpingz ...
- 阿里云CDN上线 WAF,一站式提供分发+安全能力
CDN是业界公认的加速网站访问效率.提升用户体验的内容分发加速产品.Gartner预测2019年超过50%的互联网流量将通过CDN内容分发网络进行加速. 然而,越来越多企业也意识到恶意网络攻击对非凡用 ...
- MAC中怎么安装python
转自:https://blog.csdn.net/hou_manager/article/details/79555809 一.Python 介绍 Python介绍 Python3在2008年12月3 ...
- Cf序列化器-Serializer解析
Cf序列化器-Serializer 定义序列化器 Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Seri ...
- linux学习 网络系统&文件查找
被用来配置和操作网络系统的命令数目非常巨大,这里仅仅介绍一些经常会使用的 这一章会介绍ssh远程登录程序哦 ping 命令(掠过) traceroute 会显示主机到指定的主机要经过的跳数的网络流量列 ...
- JavaScript 中的多线程通信的方法
在Html 5诞生之后,我们可以使用javascript来实现多线程处理.H5 新增了一个web workers api,使用这个API,用户可以很容易地创建在后台运行的线程,H5 中被称为workd ...
- 如何查看MySQL执行计划呢?
覆盖索引: MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 包含所有满足查询需要的数据的索引称为 覆盖索引(Covering Index) 如果要使用覆盖索引,一定 ...
- (转)Cookie存中文乱码的问题
有个奇怪的问题:登录页面中使用Cookie存值,Cookie中要存中文汉字.代码在本地调试,一切OK,汉字也能顺利存到Cookie和从Cookie中读出,但是放到服务器上不管用了,好好的汉字成了乱码, ...