禁止 UIButton 连续点击

UIButton是我们iOS开发中常用的控件,连续/抖动点击造成数据请求或其它操作重复执行也是用户使用中常发生的 !解决这一问题的方法很多,简单总结了一下.

使用UIButton的enabled或userInteractionEnabled

使用UIButton的enabled属性,点击后将enabled设置为 false, 进行任务处理,完成任务后再将其设置为 false.

@objc func btnClick(_ sender: UIButton) {
    sender.isEnabled = false
    // 网络请求
    // 数据处理
    // ....
    sender.isEnabled = true        
}

runtime 对 sendAction:to:forEvent: 进行处理

添加 UIButton 的分类,在其分类进行处理,对全局 UIButton 有效
自定义 cxg_sendAction(_ action: to:, for event:) 方法,对点击进行处理,利用 runtime 进行方法交换.
swift 取消了 load 方法,具体实现方法交换参考swift下使用runtime交换方法的实现

private var UIButton_acceptEventTime: Void?
private var UIButton_acceptInterval: Void?

extension UIButton: CXGExtensionProtocol {

    static func awake() {
        if let oldMethod = class_getInstanceMethod(self, #selector(sendAction(_:to:for:))), let newMethod = class_getInstanceMethod(self, #selector(cxg_sendAction(_:to:for:))) {
            method_exchangeImplementations(oldMethod, newMethod)
        }
    }

    // 连续点击时间间隔
    var acceptEventInterval: TimeInterval {
        get {
            if let time = objc_getAssociatedObject(self, &UIButton_acceptInterval) as? TimeInterval {
                return time
            } else {
                objc_setAssociatedObject(self, &UIButton_acceptInterval, 1, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                return 1
            }
        }
        set {
            objc_setAssociatedObject(self, &UIButton_acceptInterval, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    // 上次点击时间
    private var acceptEventTime: TimeInterval {
        get {
            if let time = objc_getAssociatedObject(self, &UIButton_acceptEventTime) as? TimeInterval {
                return time
            } else {
                objc_setAssociatedObject(self, &UIButton_acceptEventTime, 0, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                return 0
            }
        }
        set {
            objc_setAssociatedObject(self, &UIButton_acceptEventTime, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    @objc func cxg_sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        if Date().timeIntervalSince1970 - self.acceptEventTime >= acceptEventInterval {
            self.ytt_sendAction(action, to: target, for: event)
            acceptEventTime = Date().timeIntervalSince1970
        }
    }
}

下载文件UIButton+CXG,将两个文件拖入到工程,添加 AppDelegate 扩展:

extension UIApplication {
    private static let runOnce: Void = {
        CXGExtensionManager.harmlessFunction()
    }()

    override open var next: UIResponder? {
        // Called before applicationDidFinishLaunching
        UIApplication.runOnce
        return super.next
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值