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

当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
时间: 2024-10-07 05:00:12

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

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

好久之前就看到过使用Runtime解决按钮的连续点击的问题,一直觉得没啥好记录的.刚好今天旁边同时碰到这个问题,看他们好捉急而且好像很难处理,于是我先自己看看… 前面自己也学习了很多Runtime的东西,一直觉得这个按钮连续点击其实很简单,就使用Runtime交换SEL实现IMP即可,但其实没明白解决这个问题的过程. 虽然直接可以在github搜到解决方法,但是还是有必要学习一下解决这个问题的一步一步的思路,给出这个作者的git: 1 https://github.com/strivever/U

iOS小技巧--用runtime 解决UIButton 重复点击问题

iOS小技巧–用runtime 解决UIButton 重复点击问题 什么是这个问题 我们的按钮是点击一次响应一次, 即使频繁的点击也不会出问题, 可是某些场景下还偏偏就是会出问题. 通常是如何解决 我们通常会在按钮点击的时候设置这个按钮不可点击. 等待0.xS的延时后,在设置回来; 或者在操作结束的时候设置可以点击. - (IBAction)clickBtn1:(UIbutton *)sender { sender.enabled = NO; doSomething sender.enabled

利用IIS7 解决URL访问限制问题

网站可以通过URl直接访问一些不希望被访问的东西, 比如一些图片,js,css等等. 为了解决这个问题看了好多文章,不过毕竟我是新手菜鸟级别的,没有具体的解决方法,真心不知道怎么弄. 今天在看IIS的时候突然发现有一个叫"请求筛选"的东东,点击进入,发现里面可以配置筛选规则, 比如你可以自己添加 "拒绝文件扩展名",那么所有的符合你添加的那个文件扩展名的文件,都不能访问了. 具体: 打开IIS管理器--->点击你想要配置的网站,打开主页---->点击请求

AndroidStudio利用android-support-multidex解决65536问题64k问题

AndroidStudio利用android-support-multidex解决65536问题64k问题 版权声明:转载请注明本文转自严振杰的博客: http://blog.csdn.net/yanzhenjie1003 64k的各种异常 Error:The number of method references in a .dex file cannot exceed 64K.Learn how to resolve this issue at https://developer.andro

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

问题描述 我们都知道,如果我们对于一组元素(相同的标签)同时进行onclick事件处理的时候(在需要获取到索引的时候),一般是写一个for循环,但是onclick是一个异步调用的,所以会带来一个问题,当我们触发这个事件的时候,我们能获取的i值是for完整执行完后i的值,而不能获取到代码顺序里i的值 首先看一段代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title

利用gulp解决微信浏览器缓存问题

做了好多项目,这次终于要解决微信浏览器缓存这个令人头疼的问题了.每次上传新的文件,在微信浏览器中访问时,总要先清除微信的缓存,实在麻烦,在网上搜罗了很多解决办法,终于找到了方法:利用gulp解决缓存问题.关于gulp大家可以去gulp官网去详细了解. 这篇文章主要参考于Gulp解决发布线上文件(CSS和JS)缓存问题和Gulp.js----比Grunt更易用的前端构建工具两篇文章,在这里先谢过原作者. 本文主要记录安装gulp以及使用.解决缓存问题的过程,以便日后方便查阅. 1.安装NodeJS

iOS中利用 runtime 一键改变字体

http://www.cocoachina.com/ios/20160504/16109.html 本文为投稿文章,作者:HenryCheng(简书) 最近公司要在5月份举办个大型的发布会,所以在这之前要把版本稳定,界面提升,所以有很多细活要干.不过,趁前两天版本刚提交上线,这两天稍微闲一点,就把之前说的利用runtime一键改变字体的方法分享出来.有人会说,改变字体不是很简单吗,我直接找到字体名替换一下不就好了?客官不要急,先坐下来吃点瓜子,听我慢慢给你说来. 1.准备 我们新建一个项目名叫C

selector实现点击图片切换(解决常见的点击无效问题)

实现效果图:       图片未点击前                         图片点击后 selector的实现方法其实很简单,只需3步: 第一步:选择两张图片效果图放在res/drawable-hdpi中,放在mdpi也可以 第二步:在mdpi文件夹中新建xml文件,命名为selector.xml.注意名字selector后面会引用到. 在selector.xml文件中,完成代码: <?xml version="1.0" encoding="utf-8&qu

Silverlight运行时提示未安装silverlight runtime 解决方法

出现该问题是由于电脑上安装的silverlight不是silverlight developer. 一般来说安装完VS之后是不会出现该问题. 但是一旦更改了silverlight中web service中TestPage的minRuntimeVersion版本,因为默认生成的版本号是silverlight sdk(根据创建项目时选择的是silverlight 4还是5来判断是哪个版本的SDK)的版本号.一旦修改的版本号比电脑安装的sdk版本高,则会在第一次运行时提示需要安装更新版本的silver