通過extension一行代碼實現UIButton倒計時功能

  1. 通過擴展(Extension)實現UIButton倒計時
extension UIButton {
    //取消倒計時
    func cancel(backgroundColor: UIColor) {
        DispatchQueue.main.async(execute: {
            self.isEnabled = true
            self.backgroundColor = backgroundColor
            self.timer?.cancel()
            self.timer = nil
        })
    }
    struct Key {
        static var timerKey = "timerKey"
    }
    //通過關聯屬性給UIButton添加一個timer屬性,主要用來取消定時
    var timer: DispatchSourceTimer? {
        // 在調用DispatchSourceTimer時, 無論設置timer.scheduleOneshot, 還是timer.scheduleRepeating代碼 不調用cancel(), 系統會自動調用
        // 另外需要設置全局變量引用, 否則不會調用事件
        get {
            return objc_getAssociatedObject(self, &Key.timerKey) as? DispatchSourceTimer
        }
        set {
            objc_setAssociatedObject(self, &Key.timerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 開始button倒計時
    /// - Parameters:
    ///   - duration: 倒計時時間:單位秒
    ///   - disableBackGroudColor: button不可點擊時背景顏色
    ///   - disableBackGroudColor: button不可點擊時字體顏色
    func startSMSWithDuration(duration: Int, disableBackGroudColor: UIColor = .gray,disableTitleColor: UIColor = .white) {
        var times = duration
        let normalBGColor = backgroundColor
        //初始化Timer
        timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
        //timer事件處理
        timer?.setEventHandler {
            if times > 0 {
                //倒計時處理
                DispatchQueue.main.async(execute: {
                    self.isEnabled = false
                    self.setTitle("重新獲取\(times)", for: .disabled)
                    self.setTitleColor(disableTitleColor, for: .disabled)
                    self.backgroundColor = disableBackGroudColor
                    times -= 1
                })
            } else {
                //倒計時結束,取消定時,button變爲倒計時前樣式,可點擊
                DispatchQueue.main.async(execute: {
                    self.isEnabled = true
                    self.backgroundColor = normalBGColor
                    self.timer?.cancel()
                    self.timer = nil
                })
            }
        }
        timer?.schedule(deadline: .now(), repeating: .seconds(1), leeway: .milliseconds(100))
        timer?.resume()
    }
}

2.使用(一行代碼輕鬆搞定)

        //開啓定時
        button.startSMSWithDuration(duration: 60, disableBackGroudColor: .darkGray, disableTitleColor: .white)
        
        //取消定時
        button.cancel(backgroundColor: .white)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章