引言
倒计时常用于用户短信接收后,标示短信验证码的有效期。
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()
}