防止UIButton重复点击的一种简单实现(Swift)

2,035 阅读2分钟

防止UIButton重复点击的一种简单实现(Swift)

思路:

  • UIButton进行扩展,通过runtimeUIButton绑定一个属性delayTime,用来标识连续两次点击的最小时间间隔,默认是0秒
  • UIButton系统方法sendAction方法中判断每次点击时刻和上次点击时刻lastClickTime的差值是否在delayTime间隔内,落在间隔内不响应点击事件,间隔外可以响应
  • 将本次点击时刻更新给lastClickTime,作为下次点击的判断依据,循环往复

实现:

import UIKit

private var clickDelayTime = "clickDelayTime"
private var defaultDelayTime: TimeInterval = 0.0 //默认两次点击无间隔
private var lastClickTime: TimeInterval = 0.0 //记录上次点击时刻

extension UIButton {

    var delayTime: TimeInterval {
    	set {
            objc_setAssociatedObject(self, &clickDelayTime, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            if let clickDelayTime = objc_getAssociatedObject(self, &clickDelayTime) as? TimeInterval {
                return clickDelayTime
            }
            return defaultDelayTime
        }
    }
    
    open override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
    	// 未设置delayTime值或者设置为0s间隔
        if delayTime == 0 {
            super.sendAction(action, to: target, for: event)
        } else {
        	// 这里当前点击时刻用timeIntervalSince1970作为参考值,也可以取其他
            // 两次点击时间间隔大于设定值,响应
            if Date().timeIntervalSince1970 - lastClickTime > delayTime {
                super.sendAction(action, to: target, for: event)
                // 更新本次点击时刻
                lastClickTime = Date().timeIntervalSince1970
            }
        }
    }
}

在控制器中放两个button,红色button设置delayTime = 2,绿色button不设置delayTime属性

import UIKit

class ViewController: UIViewController {
    
    lazy var button1: UIButton = {
        let button = UIButton.init(type: .custom)
        button.backgroundColor = .red
        button.addTarget(self, action: #selector(button1Action(_:)), for: .touchUpInside)
        button.delayTime = 2
        return button
    }()
    
    lazy var button2: UIButton = {
        let button = UIButton.init(type: .custom)
        button.backgroundColor = .green
        button.addTarget(self, action: #selector(button2Action(_:)), for: .touchUpInside)
        return button
    }()
    
    @objc func button1Action(_ btn: UIButton) {
        print("button1点击时刻: \(Date().timeIntervalSince1970)")
    }
    
    @objc func button2Action(_ btn: UIButton) {
        print("button2点击时刻: \(Date().timeIntervalSince1970)")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        button1.frame = CGRect.init(x: 50, y: 50, width: 100, height: 100)
        button2.frame = CGRect.init(x: 50, y: 200, width: 100, height: 100)
        view.addSubview(button1)
        view.addSubview(button2)
    }
}

对两个button进行频繁的点击测试,看打印结果:

button1点击时刻: 1597386971.018733
button1点击时刻: 1597386973.0750499
button1点击时刻: 1597386975.1070518
button1点击时刻: 1597386977.139117

button2点击时刻: 1597387094.007613
button2点击时刻: 1597387094.0644488
button2点击时刻: 1597387094.2047992
button2点击时刻: 1597387094.356614

button1两次点击之间有2秒的时间间隔,button2没有限制