按钮单击两次

时间:2017-08-04 10:13:02

标签: swift button

众所周知,为了避免点击两次,我们可以在tap方法下设置代码并添加一个HUD,如SVProgress.show()。

isUserInteractionEnabled = false

网络请求后,将其设置为true和SVProgress.dismiss()。 我想知道是否有一种方法来提取那些需要发送请求的按钮的功能。我曾想过用方法调配。将其添加到按钮扩展名,代码如下。看起来不太好。你们有一些很好的方法来提取功能吗?使用继承,协议还是别的什么?

extension UIButton {
    private struct AssociatedKeys {
        static var cp_submitComplete = "cp_submitComplete"
        static var cp_defaultMessage:String = NSLocalizedString("Loading", comment: "prompt")
        static var cp_customMessage = "cp_customMessage"
    }

    var submitNotComplete: Bool {
        get {
            let objc_Get = objc_getAssociatedObject(self, &AssociatedKeys.cp_submitComplete)
            if objc_Get != nil {
                if let objc_Get = objc_Get as? Bool, objc_Get == true {
                    return true
                }
                return false
            } else {
                return false
            }
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.cp_submitComplete, newValue as Bool, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            if !newValue {
                isUserInteractionEnabled = true
                SVProgressHUD.dismiss()
            }
        }
    }

    var customMessage: String {
        get {
            let cp_customMessage = objc_getAssociatedObject(self, &AssociatedKeys.cp_customMessage)
            if let message = cp_customMessage {
                return message as! String
            } else {
                return AssociatedKeys.cp_defaultMessage
            }
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.cp_customMessage, newValue as String, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    override open class func initialize() {
        if self == UIButton.self {
            DispatchQueue.once(NSUUID().uuidString, block: {
                let systemSel = #selector(UIButton.sendAction(_:to:for:))
                let swizzSel = #selector(UIButton.cpSendAction(_:to:for:))

                let systemMethod = class_getInstanceMethod(self, systemSel)
                let swizzMethod = class_getInstanceMethod(self, swizzSel)

                let isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod))

                if isAdd {
                    class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
                } else {
                    method_exchangeImplementations(systemMethod, swizzMethod);
                }
            })
        }
    }

    private dynamic func cpSendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {

        cpSendAction(action, to: target, for: event)
        if submitNotComplete {
            //begin submit
            isUserInteractionEnabled = false
            SVProgressHUD.show(withStatus: customMessage)
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我认为在UIButton中处理这种逻辑是个坏主意。我宁愿让视图控制器负责启用/禁用按钮。

func handleTap(_ sender: UIButton) {
    sender.isEnabled = false
    SVProgressHUD.show(withStatus: customMessage)
    doSomeTaskAsync(withCompletion: {
        sender.isEnabled = true
        SVProgressHUD.dismiss()
    })
}