一)使用场景
多用于页面活动展示剩余天数倒计时;
- 效果如下;
- 支持后台持续计时;
- 同一个数据源,遵循代理,支持多处数据共享;
二)使用方法
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
}
}
网友评论