美文网首页ios
iOS按钮防止被重复点击的方法

iOS按钮防止被重复点击的方法

作者: SwordDevil | 来源:发表于2017-11-23 15:20 被阅读35次

    简介

    对于按钮来说会存在多次点击 当程序卡住的时候 多次点击按钮会引起跳转多次页面、也获取引起多次请求,在这里总结三种防止重复点击的方法

    第一种:每次在点击时先取消之前的操作

    - (void)buttonAction:(id)sender
    {
        [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(buttonAction:) object:sender];
        [self performSelector:@selector(buttonAction:) withObject:sender afterDelay:0.2f];
    }
    

    第二种:点击后设为不可被点击的状态,几秒后恢复:

    -(void)buttonAction:(id)sender
    {
        self.button.enabled = NO;
        [self performSelector:@selector(changeButtonStatus) withObject:sender afterDelay:1.0f];//防止重复点击
    }
    -(void)changeButtonStatus
    {
        self.button.enabled = YES;
    }
    

    第三种:使用runtime,一劳永逸我这设的是0.5秒内不会被重复点击

    1.导入#import <objc/runtime.h>(可以放在PCH文件里)
    2.创建UIControl或UIButton的的分类!
    创建分类文件:
    2.1 打开Xcode中,新建文件,选择OC文件
    2.2 在第二个界面,File名为UIControl+ButtonCon.h,将文件类型File Type选为Category类,在类里选继承的类别,这里咱们选的Class是UIButton
    注:若用UIButton分类,则会对对UIButton创建的按钮反应。
    2.3 分类创建完毕对分类进行操作

    .h文件

    #import <UIKit/UIKit.h>
    #import <objc/runtime.h>
    
    #define defaultInterval .5  //默认时间间隔
    @interface UIControl (ButtonCon)
    
    @property(nonatomic,assign)NSTimeInterval timeInterval;  //用这个给重复点击加间隔
    @property(nonatomic,assign)BOOL isIgnoreEvent;  //YES不允许点击NO允许点击
    
    @end
    

    .m文件

    #import "UIControl+ButtonCon.h"
    
    @implementation UIControl (ButtonCon)
    
    - (NSTimeInterval)timeInterval
    {
        return [objc_getAssociatedObject(self, _cmd) doubleValue];
    }
    
    - (void)setTimeInterval:(NSTimeInterval)timeInterval
    {
        objc_setAssociatedObject(self, @selector(timeInterval), @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    //runtime动态绑定属性
    - (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent
    {
        objc_setAssociatedObject(self, @selector(isIgnoreEvent), @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (BOOL)isIgnoreEvent
    {
        return [objc_getAssociatedObject(self, _cmd) boolValue];
    }
    
    - (void)resetState
    {
        [self setIsIgnoreEvent:NO];
    }
    
    + (void)load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            SEL selA = @selector(sendAction:to:forEvent:);
            SEL selB = @selector(mySendAction:to:forEvent:);
            Method methodA = class_getInstanceMethod(self, selA);
            Method methodB = class_getInstanceMethod(self, selB);
            //将methodB的实现添加到系统方法中也就是说将methodA方法指针添加成方法methodB的返回值表示是否添加成功
            BOOL isAdd = class_addMethod(self, selA, method_getImplementation(methodB), method_getTypeEncoding(methodB));
            //添加成功了说明本类中不存在methodB所以此时必须将方法b的实现指针换成方法A的,否则b方法将没有实现。
            if (isAdd) {
                class_replaceMethod(self, selB, method_getImplementation(methodA), method_getTypeEncoding(methodA));
            } else {
                //添加失败了说明本类中有methodB的实现,此时只需要将methodA和methodB的IMP互换一下即可。
                method_exchangeImplementations(methodA, methodB);
            }
        });
    }
    
    - (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent*)event
    {
        if ([NSStringFromClass(self.class) isEqualToString:@"UIButton"]) {
            self.timeInterval = self.timeInterval == 0 ? defaultInterval : self.timeInterval;
            if (self.isIgnoreEvent) {
                return;
            } else if (self.timeInterval > 0) {
                [self performSelector:@selector(resetState) withObject:nil afterDelay:self.timeInterval];
            }
        }
        //此处methodA和methodB方法IMP互换了,实际上执行sendAction;所以不会死循环
        self.isIgnoreEvent = YES;
        [self mySendAction:action to:target forEvent:event];
    }
    
    @end
    

    结束语

    到这里就结束了,如若不懂的话可以👇留言,也可以加入群讨论
    喜欢的话 记得关注、收藏、点赞哟

    群号:552048526

    相关文章

      网友评论

        本文标题:iOS按钮防止被重复点击的方法

        本文链接:https://www.haomeiwen.com/subject/cmyzvxtx.html