花落√莫相思

79-Swift 之倒计时

2017-10-30  本文已影响116人  NetWork小贱

引言

倒计时常用于用户短信接收后,标示短信验证码的有效期。

Swift 中常见的倒计时有一下四个

1、Timer的自动倒计时,不用添加到循环中(RunLoop)

// MARK: 倒计时一
func countDown_1(interval:TimeInterval) -> Void {
    /*!
     @withTimeInterval 定时器间隔时间
     @repeats 定时器是否重复触发
     @block 定时器触发后的一个回调
     */
    Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: { (timer) in
        if self.timeCount != 0 {
            self.timeCount -= 1
            self.totalLable?.text = String.localizedStringWithFormat("%ds重新获取",self.timeCount)
        }else if self.timeCount == 0 {
            timer.invalidate()
            self.totalLable?.text = "获取验证码"
        }
    });
}

2、 Timer不自动触发,只执行一次,需要加入循环,和手动触发

// MARK: 倒计时二
func countDown_2(interval:TimeInterval) -> Void {
    myTimer = Timer.init(timeInterval: interval, target: self, selector: #selector(timeDownClick), userInfo: ["userInfo":"Network小贱"], repeats: true)
    // 加入到RunLoop中,否则不循环,只执行一次
    RunLoop.main.add(myTimer, forMode: .defaultRunLoopMode)
    // 起动定时器
    myTimer.fire()
}
// 定时器的事件响应
@objc func timeDownClick() {
    if self.timeCount != 0 {
        self.timeCount -= 1
        self.totalLable?.text = String.localizedStringWithFormat("%ds重新获取",self.timeCount)
    }else if self.timeCount == 0 {
        myTimer.invalidate()
        self.totalLable?.text = "获取验证码"
    }
}

3、 屏幕刷新频率(CADisplayLink)的倒计时实现

// MARK: 倒计时三
func countDown_3(interval:TimeInterval) -> Void {
    displayLink = CADisplayLink.init(target: self, selector: #selector(displayLinkClick))
    // 设置调用时间
    if #available(iOS 3.1 ,*) {
        displayLink.preferredFramesPerSecond = Int(interval)
    }
    else  {
        displayLink.frameInterval = Int(interval)
    }
    displayLink.preferredFramesPerSecond = Int(interval)
    // 加入RunLoop中
    displayLink.add(to: RunLoop.main, forMode: .defaultRunLoopMode)
}
// 定时器执行事件
@objc func displayLinkClick(){
    if self.timeCount != 0 {
        self.timeCount -= 1
        self.totalLable?.text = String.localizedStringWithFormat("%ds重新获取",self.timeCount)
    }else if self.timeCount == 0 {
        displayLink.remove(from: RunLoop.main, forMode: .defaultRunLoopMode)
        displayLink.invalidate()
        self.totalLable?.text = "获取验证码"
    }
}

4、 GCD 倒计时的实现

注意:要创建全局对象(var sourceTimer :DispatchSourceTimer!),手动触发。

// MARK: 倒计时4
func countDown_4(interval:TimeInterval) -> Void {
    sourceTimer = DispatchSource.makeTimerSource()
    sourceTimer.schedule(deadline:.now()+interval, repeating: DispatchTimeInterval.milliseconds(1000), leeway: DispatchTimeInterval.milliseconds(0))
    sourceTimer.setEventHandler {
        if self.timeCount != 0 {
            self.timeCount -= 1
            DispatchQueue.main.async {
                self.totalLable?.text = String.localizedStringWithFormat("%ds重新获取",self.timeCount)
            }
        }else if self.timeCount == 0 {
            self.sourceTimer.cancel()
            DispatchQueue.main.async {
                self.totalLable?.text = "获取验证码"
            }
        }
    }
    // 启动定时器
    sourceTimer.resume()
}
上一篇下一篇

猜你喜欢

热点阅读