Swift 倒计时按钮

import UIKit

public enum CountdownState: Int {
    case normal = 0, countdown, reget
}

typealias CountdownButtonCallBack = (CountdownButton, CountdownState, Int) -> Void

/// 倒计时按钮
class CountdownButton: UIButton {
    
    /// 按钮状态
    private var _state: CountdownState! {
        didSet {
            if let state = _state {
                _totalCount = totalCount
                isEnabled = state != .countdown
                callback(self, _state, _totalCount)
                if (state == .countdown) {
                    if (timer == nil) {
                        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)
                        timer?.fire()
                    }
                } else {
                    if (timer != nil) {
                        timer?.invalidate()
                        timer = nil
                    }
                }
            }
        }
    }
    
    /// 按钮回调
    private var callback: CountdownButtonCallBack!
    
    /// 计时器
    private var timer: Timer?
    
    /// 计时计数
    private var _totalCount: Int = 0
    
    /// 默认计数
    private var totalCount: Int = 10
    
    /// 初始化
    public convenience init(frame: CGRect, callback: @escaping CountdownButtonCallBack) {
        self.init(frame: frame)
        self.callback = callback
        reset()
    }
    
    /// 开始
    public func start(_ count: Int = 60) {
        totalCount = count
        _state = .countdown
    }
    
    /// 结束
    public func stop() {
        _state = .reget
    }
    
    /// 重置
    public func reset() {
        _state = .normal
    }
    
    /// 计时器方法
    @objc private func countdown() {
        if (_totalCount <= 0) {
            stop()
        } else {
            callback(self, _state, _totalCount)
            _totalCount -= 1
        }
    }
    
    /// 初始化
    private override init(frame: CGRect) {
        super.init(frame: frame)
    }

    /// 停止计时器
    override func removeFromSuperview() {
        super.removeFromSuperview()
        stop()
    } 
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

调用方式

import UIKit

class ViewController: UIViewController {
    
    var btn: CountdownButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        
        btn = CountdownButton(frame: .zero, callback: { btn, state, count in
            switch state {
            case .normal:
                btn.setTitle("获取验证码", for: .normal)
                btn.setTitleColor(.black, for: .normal)
                btn.backgroundColor = .yellow
            case .countdown:
                btn.setTitle("\(count)秒", for: .normal)
                btn.setTitleColor(.red, for: .normal)
                btn.backgroundColor = .blue
            case .reget:
                btn.setTitle("重新获取", for: .normal)
                btn.setTitleColor(.black, for: .normal)
                btn.backgroundColor = .yellow
            }
        })
        btn.addTarget(self, action: #selector(btnClick(_:)), for: .touchUpInside)
        view.addSubview(btn)
        
        btn.snp.makeConstraints { (make) in
            make.left.equalTo(50)
            make.top.equalTo(100)
            make.height.equalTo(80)
            make.width.equalTo(200)
        }
    }

    @objc private func btnClick(_ sender: UIButton) {
        btn.start()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 获取验证码倒计时的按钮。 在你需要的时候调用: 这样就实现了你的获取验证码倒计时,不过还有一个最重要的问题:当你初...
    追梦小怪兽阅读 2,508评论 0 4
  • 参照网上的一个倒计时按钮,以学习的目的抄了一下,根据自己的理解修改了一些内容,使倒计时按钮用起来更方便了些。因为是...
    梦里风吹过阅读 3,232评论 1 11
  • 定义变量 调用完成获取验证码接口后,启动计时器 异步刷新页面按钮的文字
    晴天mk1992阅读 662评论 0 1
  • 根据网上的方法优化完善了一下。button样式如字体颜色、背景色没做说明,自行按需修改。 1:创建一个计时器 pr...
    LX950124阅读 1,758评论 0 1
  • 路过火车桥洞的那个下午,阳光热得发烫,却照得我心里无比的荒凉,她的背影和路边的那个沙丘一起不知道消失了多久了...
    西小麦阅读 3,921评论 72 113

友情链接更多精彩内容