美文网首页
iOS UIButton按钮防止重复点击

iOS UIButton按钮防止重复点击

作者: ufogxl | 来源:发表于2021-09-27 21:48 被阅读0次

    开发app过程中我们经常会遇到按钮多次重复点击后出现不想看到的情况,比如多次push到下一个页面,多次添加到同一个数据等,这时我们就要考虑在点击后,能够限制用户继续点击这个按钮。

    比较常见的解决有以下几种:

    一、在点击事件中将按钮的isEnabled设置为false,确认可以再次点击再改回true

    @objc func tapButton(button:UIButton){
        button.isEnabled = false
        DispatchQueue.main.asyncAfter(deadline: .now() + 2){
            button.isEnabled = true;
        }
    }
    

    二、给当前页面设置loading蒙版,比如使用SVProgressHUD:

    @objc func tapButton(button:UIButton){
        SVProgressHUD.show()
        DispatchQueue.main.asyncAfter(deadline: .now() + 2){
            SVProgressHUD.dismiss()
        }
    }
    

    三、使用方法交换,给按钮的的点击设置时间间隔

    这里交换的是UIButton.sendAction(_:to:for:)方法

    1.新增时间间隔控制关联对象

    let isEventUnavailableKey = "isEventUnavailableKey"
    let eventIntervalKey = "eventIntervalKey"
    extension UIButton{
        //事件间隔
        var eventInterval: TimeInterval {
            get {
                return (objc_getAssociatedObject(self, &UIButtonKey.eventIntervalKey) as? TimeInterval) ?? 0
            }
            set {
                objc_setAssociatedObject(self, &UIButtonKey.eventIntervalKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
        //是否可用标志
        var isEventUnavailable: Bool {
            get {
                return (objc_getAssociatedObject(self, &UIButtonKey.isEventUnavailableKey) as? Bool) ?? false
            }
            set {
                objc_setAssociatedObject(self, &UIButtonKey.isEventUnavailableKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
    

    2.新增点击事件方法

    @objc func intervalSendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        if isEventUnavailable == false {
            isEventUnavailable = true
            mySendAction(action, to: target, for: event)
            perform(#selector(setIsEventUnavailable(_: )), with: false, afterDelay: eventInterval)
        }
    }
    

    3.方法交换

    extension UIButton{
        static let once:Void = {
            exchange()
        }()
        
        static func exchange(){
            let original = #selector(UIButton.sendAction(_:to:for:))
            let swizzled = #selector(UIButton.sendAction .intervalSendAction(_:to:for:))
            
            guard let originalMethod = class_getInstanceMethod(UIButton.self, original),
                  let swizzledMethod = class_getInstanceMethod(UIButton.self, swizzled) else {
                return
            }
            
            let didAddMethod = class_addMethod(UIButton.self, original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
            if didAddMethod {
                class_replaceMethod(UIButton.self, swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod)
            }
        }
    }
    

    4.最后在按钮被点击之前(如app入口)处调用方法交换

    UIButton.once
    

    5.给按钮设置间隔

    button.eventInterval = 2
    

    ----------完成-----------

    相关文章

      网友评论

          本文标题:iOS UIButton按钮防止重复点击

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