iOS UIButton按钮防止重复点击

2021-09-27  本文已影响0人  ufogxl

开发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

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

上一篇下一篇

猜你喜欢

热点阅读