当app有点卡的时候,多次点击相同的button,经常出现,跳转了N次相同的界面(比如闲鱼)

解决办法

用运行时和分类,替换 UIControl 响应事件,根据响应的间隔时间来判断是否执行事件。

详细步骤

  1. UIControl

    创建一个 UIControl 的分类

    Snip20160816_3.png

Snip20160816_4.png

为了方便他人调整不同的间隔时间需求,在 UIControl+Custom.h 文件中开放间隔时间属性, UIControl+Custom.h 文件的代码为:

//  UIControl+Custom.h
//  Created by ocarol on 16/8/16.
//  Copyright © 2016年 ocarol. All rights reserved.
//  
#import <UIKit/UIKit.h>  
@interface UIControl (Custom)
@property (nonatomic, assign) NSTimeInterval custom_acceptEventInterval;// 可以用这个给重复点击加间隔
@end

在 UIControl+Custom.m 文件中实现方法交换(妥善的做法是:先添加方法,如果方法已经存在,就替换原方法),在 UIControl+Custom.m 文件的代码为:

//  UIControl+Custom.m
//  Created by ocarol on 16/8/16.
//  Copyright © 2016年 ocarol. All rights reserved.
//
#import "UIControl+custom.h"
#import <objc/runtime.h>
@interface UIControl()
@property (nonatomic, assign) NSTimeInterval custom_acceptEventTime;
@end
@implementation UIControl (Custom)
+ (void)load{    
   Method systemMethod = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));    
   SEL sysSEL = @selector(sendAction:to:forEvent:);    
   Method customMethod = class_getInstanceMethod(self, @selector(custom_sendAction:to:forEvent:));    
   SEL customSEL = @selector(custom_sendAction:to:forEvent:);      
   //添加方法 语法:BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) 若添加成功则返回No    
   // cls:被添加方法的类  name:被添加方法方法名  imp:被添加方法的实现函数  types:被添加方法的实现函数的返回值类型和参数类型的字符串    
   BOOL didAddMethod = class_addMethod(self, sysSEL, method_getImplementation(customMethod), method_getTypeEncoding(customMethod));      
   //如果系统中该方法已经存在了,则替换系统的方法  语法:IMP class_replaceMethod(Class cls, SEL name, IMP imp,const char *types)    
   if (didAddMethod) {        
       class_replaceMethod(self, customSEL, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));    
   }else{        
       method_exchangeImplementations(systemMethod, customMethod);      
   }
}
- (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);
}
- (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);
}
- (void)custom_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{    
   // 如果想要设置统一的间隔时间,可以在此处加上以下几句    
   // 值得提醒一下:如果这里设置了统一的时间间隔,会影响UISwitch,如果想统一设置,又不想影响UISwitch,建议将UIControl分类,改成UIButton分类,实现方法是一样的    
   // if (self.custom_acceptEventInterval <= 0) {    
   //     // 如果没有自定义时间间隔,则默认为2秒    
   //    self.custom_acceptEventInterval = 2;    
   // }      
   // 是否小于设定的时间间隔    
   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];    
   }  
}
@end

利用 runtime,解决多次点击相同 button,导致重复跳转的问题-b的更多相关文章

  1. 多次快速点击相同button导致重复响应的问题

    Button在开发中经常用到,但是如果在瞬间点击多次时会出现多次响应事件的问题,今天给大家分享一下解决方法. 方法一:在Button响应事件中禁止Button允许点击, -(void)buttonAc ...

  2. 利用RunTime解决由NSTimer导致的内存泄漏

    NSTimer使用场景 用NSTimer来实现每隔一定时间执行制定的任务,例如最常见的广告轮播图,使用NSTimer实现这个功能很简单代码如下 NSTimer *_timer; _timer = [N ...

  3. Runtime应用防止按钮连续点击 (转)

    好久之前就看到过使用Runtime解决按钮的连续点击的问题,一直觉得没啥好记录的.刚好今天旁边同时碰到这个问题,看他们好捉急而且好像很难处理,于是我先自己看看… 前面自己也学习了很多Runtime的东 ...

  4. 利用NSProxy解决NSTimer内存泄漏问题

    之前写过一篇利用RunTime解决由NSTimer导致的内存泄漏的文章,最近和同事讨论觉得这样写有点复杂,然后发现有NSProxy这么好用的根类,根类,根类,没错NSProxy与NSObject一样是 ...

  5. 利用闭包解决for循环里onclick事件不能捕捉实时i值问题

    问题描述 我们都知道,如果我们对于一组元素(相同的标签)同时进行onclick事件处理的时候(在需要获取到索引的时候),一般是写一个for循环,但是onclick是一个异步调用的,所以会带来一个问题, ...

  6. iOS - 利用runtime加深对基础知识的理解

    利用runtime加深对基础知识的理解 如果对runtime需要学习,可以看这篇,以下仅作为学习笔记,相互交流. runtime的头文件: #import <objc/runtime.h> ...

  7. iOS中利用 runtime 一键改变字体

    1.准备 我们新建一个项目名叫ChangeFont,然后我就随便找了个名叫loveway.ttf的字体库拖进去,里面的工程目录大概就是这样的 目录 现在我们就简单的直接在storyboard上拖了一个 ...

  8. iOS利用Runtime自定义控制器POP手势动画

    前言 苹果在iOS 7以后给导航控制器增加了一个Pop的手势,只要手指在屏幕边缘滑动,当前的控制器的视图就会跟随你的手指移动,当用户松手后,系统会判断手指拖动出来的大小来决定是否要执行控制器的Pop操 ...

  9. 利用Readability解决网页正文提取问题

    分享: 利用Readability解决网页正文提取问题   做数据抓取和分析的各位亲们, 有没有遇到下面的难题呢? - 如何从各式各样的网页中提取正文!? 虽然可以用SS为各种网站写脚本做解析, 但是 ...

随机推荐

  1. iOS安全攻防

    iOS安全攻防 http://www.docin.com/p-760264769.html

  2. java基础学习总结五(递归算法、冒泡排序、查看生成API)

    一:递归算法 概念:自己调用自己的方法 示例代码如下: @Test /** * 递归求和 * 5+4+3+2+1=15 */ public void getSum() { long sum = sum ...

  3. scrollLeft,scrollWidth,clientWidth,offsetWidth 可实现导航栏固定不动(冻结)的效果

    HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth  scrollHeight: 获取对象的滚动高度.  scrollLeft:设置或获取位 ...

  4. java.lang.ClassFormatError: Illegal UTF8 string in constant pool in class file Server/Request

    Linux服务器上,将本地编译好的文件上传后,Tomcat启动时报错: Exception in thread "Thread-2" java.lang.ClassFormatEr ...

  5. yii2 ./yii command : No such file or directory

    git clone下来的yii2后台项目,由于需要执行 ./yii migrate命令.执行之后,提示 No such file or directory 我从同样为yii2 basic的./yii ...

  6. asp.net 编写验证码

    首先准备一个类来实现对验证码的绘制功能. createcode.cs using System; using System.Collections.Generic; using System.Linq ...

  7. Unity3D之Ugui 制作弹框

    创建一个UI控件. 这里通过按钮的点击取控制弹框的显示或者隐藏.给按钮Button绑定一个脚本. 将Panel初始化设置为隐藏.就可以实现了. using UnityEngine; using Sys ...

  8. ResourceManager高可用配置

    ResourceManager高可用配置 1. yarn-site.xml配置 <property> <name>yarn.resourcemanager.cluster-id ...

  9. openvswitch安装和使用 --修订通用教程的一些错误

    1.下载openvswitch源文件,注意版本要适合操作系统内核. 推荐openvswitch2.0及其以上版本. 2.开始安装openvswitch cd openvswitch sudo ./bo ...

  10. C#之装箱和拆箱

    在实际编码过程中,有时候会出现装箱和拆箱操作.下面就类分别认识一下: 需要注意的是,类型转换和这个是不同的.Convert方法并没有发生装箱和拆箱操作,而是类型转换,包括int.parse等等. 装箱 ...