Swift

iOS 全网最准确的倒计时方法

2021-11-18  本文已影响0人  KingWorld

背景:因为app上用到很多倒计时,但是当app挂在后台或者有其它情况,就很容易导致倒计时计时不准确,为此有一个提高倒计时的准确性方法

方法概念

1.后端返回后端服务器时间与准备开始时间,计算出两者时间差
2.用手机当前时间与时间差每秒相减,就是倒计时的值
//活动 3: 进行中 2:未开始 1:已结束
    var sort = 1
    //结束时间
    var date_end = ""
    //开始时间
    var date_start = ""
    //系统当前时间
    var current_time = ""
    //倒计时日历
    var com:DateComponents?
    //倒计时相差秒数
    var instanceT: Int64?
    var instanceTime : Int64?{
        get{
            if let t = instanceT{
                return t
            }
            let format = DateFormatter()
            format.dateFormat = "yyyy-MM-dd HH:mm:ss"
            var endT : Date
            if sort == 2 {
                endT = format.date(from: date_start) ?? Date()
            } else if sort == 3 {
                endT = format.date(from: date_end) ?? Date()
            } else {
                endT = Date()
            }
            
            let endSeconds = endT.timeIntervalSince1970
            let currentT = format.date(from: current_time)
            let currentSeconds = currentT?.timeIntervalSince1970
            //计算相差秒数
            if let current = currentSeconds,endSeconds > current {
                instanceT = Int64(endSeconds - current)
                return Int64(endSeconds - current)
            }
            return nil
        }
        set{
            instanceT = newValue
        }
    }

在cell上

var timer : DispatchSourceTimer?

func setUpTimer(vm:ViewModel) {
        if let _ = timer{
            return;
        }
        if let insatnceT = vm.instanceTime,insatnceT > 0{
            //将相差秒数与当前手机时间相加,到时候用这时间每秒减去当前时间用来倒数
            entTime = Date().timeIntervalSince1970 + Double(insatnceT)
            handTime(insatnceT)

            timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
            //        let timer = DispatchSource.makeTimerSource()
                /*
                dealine: 开始执行时间
                repeating: 重复时间间隔
                leeway: 时间精度
            */
            timer?.schedule(deadline: .now(), repeating: DispatchTimeInterval.seconds(1), leeway: DispatchTimeInterval.seconds(0))
                    // timer 添加事件
            timer?.setEventHandler {[weak self] in
                //每秒减去当前时间用来倒数
                if let endT = self?.entTime,endT - Date().timeIntervalSince1970 > 0{
                    let insatnceT = endT - Date().timeIntervalSince1970
                    DispatchQueue.main.async {
                        self?.handTime(Int64(insatnceT))
                    }
                }else{
                    DispatchQueue.main.async {
                        //处理UI界面
                        self?.timeLabList[1].text = "00"
                        self?.timeLabList[2].text = "00"
                        self?.timeLabList[3].text = "00"
                    }
                    //倒数结束后将timer释放
                    self?.removeData()
                    //时间倒数结束之后回调
                    self?.didTimeOver?()
                }
            }
            timer?.resume()
        }
    }
    
    func removeData(){
        guard let t = timer else {
            return
        }
        t.cancel()
        timer = nil
    }
    
//根据秒数计算出天,时,分,秒
func handTime(_ seconds:Int64){
    var remainS = seconds
    let days = remainS/(24 * 60 * 60)
    remainS = remainS%(24 * 60 * 60)
    let h = remainS/(60 * 60)
    remainS = remainS%(60 * 60)
    let m = remainS/60
    let s = remainS%60
}

上一篇下一篇

猜你喜欢

热点阅读