zoukankan      html  css  js  c++  java
  • 利用 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
  • 相关阅读:
    LeetCode 1122. Relative Sort Array (数组的相对排序)
    LeetCode 46. Permutations (全排列)
    LeetCode 47. Permutations II (全排列 II)
    LeetCode 77. Combinations (组合)
    LeetCode 1005. Maximize Sum Of Array After K Negations (K 次取反后最大化的数组和)
    LeetCode 922. Sort Array By Parity II (按奇偶排序数组 II)
    LeetCode 1219. Path with Maximum Gold (黄金矿工)
    LeetCode 1029. Two City Scheduling (两地调度)
    LeetCode 392. Is Subsequence (判断子序列)
    写程序判断系统是大端序还是小端序
  • 原文地址:https://www.cnblogs.com/isItOk/p/5838212.html
Copyright © 2011-2022 走看看