美文网首页
(Swift)活动剩余天数倒计时

(Swift)活动剩余天数倒计时

作者: 布呐呐u | 来源:发表于2021-08-30 14:41 被阅读0次

    一)使用场景

    多用于页面活动展示剩余天数倒计时;

    • 效果如下;
    • 支持后台持续计时;
    • 同一个数据源,遵循代理,支持多处数据共享;
    filename.gif

    二)使用方法

    class CCUserViewController: CCViewController, CCCountDownManageProtocol {
        
        /// 懒加载显示UILabel控件
        lazy var tipsLabel: UILabel = { UILabel() }()
        
        /// CCCountDownManage代理方法
        func refreshTime(result: [String]) {
            tipsLabel.text = "\(result[0])天,\(result[1])时,\(result[2])分,\(result[3])秒"
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // ①添加代理
            CCCountDownManage.shared.deletage = self
            // ②执行倒计时方法
            CCCountDownManage.shared.run(start: 1630302821, end: 1636302821)
            
            tipsLabel.font = MediumFont(16)
            tipsLabel.backgroundColor = .main
            tipsLabel.textAlignment = .center
            tipsLabel.layer.cornerRadius = 6
            tipsLabel.layer.masksToBounds = true
            view.addSubview(tipsLabel)
            tipsLabel.snp.makeConstraints { make in
                make.center.equalToSuperview()
                make.size.equalTo(CGSize(width: 160, height: 36))
            }
            
            // ③若初始化时,代理返回值有延迟,则可手动调用updateRemainingTime方法,优先渲染一次数据(可选行为)
            var res = [String]()
            res = CCCountDownManage.shared.updateRemainingTime()
            tipsLabel.text = "\(res[0])天,\(res[1])时,\(res[2])分,\(res[3])秒"
        }
    }
    

    三)源码分享

    //
    //  CCCountDownManage.swift
    //  HelloSwift
    //
    //  Created by a51095 on 2021/7/15.
    //
    
    protocol CCCountDownManageProtocol: NSObjectProtocol {
        func refreshTime(result: [String])
    }
    
    // eg: 添加CCCountDownManage代理对象,并实现CCCountDownManageProtocol协议,协议方法中,即可获取倒计时总时长(天,时,分,秒)
    final class CCCountDownManage {
        static var shared = CCCountDownManage()
        
        /// 倒计时总时长
        private var countDownTotal: Int = 0
        /// 当前系统绝对时间,进入后台后,仍持续计时
        private var startTime: Int = 0
        /// 代理对象
        public weak var deletage: CCCountDownManageProtocol?
        /// 定时器对象
        private lazy var taskTimer: DispatchSourceTimer? = {
            let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
            return timer
        }()
        
        /// 开始活动倒计时
        public func run(start: Int, end: Int) {
            guard end - start > 0 else { return }
            
            countDownTotal = end - start
            startTime = Int(CACurrentMediaTime())
            
            taskTimer?.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(0))
            taskTimer?.setEventHandler {
                self.deletage?.refreshTime(result: self.updateRemainingTime())
            }
            taskTimer?.resume()
        }
        
        // MARK: - 获取剩余总时长
        private func remainingTime() -> Int {
            countDownTotal - (Int(CACurrentMediaTime()) - startTime)
        }
        
        /// 更新剩余总时长
        public func updateRemainingTime() -> [String] {
            var resultString = "00:00:00:00"
            let remainingTotal = remainingTime()
            if remainingTotal > 0 {
                let day = remainingTotal / (24 * 60 * 60)
                let hours = remainingTotal / (60 * 60) - day * 24
                let minutes = remainingTotal / 60 - (day * 24 * 60) - (hours * 60)
                let seconds = remainingTotal % 60
                resultString = (String(format: "%02d:%02d:%02d:%02d",day, hours, minutes, seconds))
            }else {
                taskTimer?.cancel()
            }
            return resultString.components(separatedBy: ":")
        }
        
        /// 手动停止定时器,并释放定时器对象
        public func cannel() {
            taskTimer?.cancel()
            taskTimer = nil
        }
    }
    
    

    四)更多组件,传送门

    Demo

    相关文章

      网友评论

          本文标题:(Swift)活动剩余天数倒计时

          本文链接:https://www.haomeiwen.com/subject/dpfoiltx.html