Swift实现倒计时5秒功能

时间:2021-05-20

一般在项目的“引导页”有个功能,倒计时5秒结束后,然后可以允许用户点击跳过按钮跳过引导页。同样在“登录”和“注册”页面也有类似功能,发送验证码后,计时60秒后才允许用户再次请求重新发送验证码。

计时方式一(sleep + performSelector)

通过调用sleep(1)阻塞线程的方式来达到目的

import UIKit class GAPublishViewController: GABaseViewController { var jumpBut = UIButton(frame: CGRect(x: 15, y: 64, width: 80, height: 40)); var limitTime: Int = 5+1; override func viewDidLoad() { super.viewDidLoad() setupJumpButton(); startCountDown(); } func setupJumpButton() { view.addSubview(jumpBut); jumpBut.setTitle("跳过(5S)", for: .normal); jumpBut.setTitleColor(UIColor.red, for: .normal); jumpBut.addTarget(self, action: #selector(tapJumpAction(sender:)), for: .touchUpInside); } @objc func tapJumpAction(sender: Any) { let but = sender as! UIButton; let text = but.titleLabel?.text ?? ""; if (text == "跳过") { print("点击“跳过”"); } } // MARK: 定时方式一 func startCountDown() { performSelector(inBackground: #selector(countDownThread), with: nil) } @objc func countDownThread() { let timeCount = limitTime; for _ in 0..<timeCount { limitTime = limitTime - 1; self.performSelector(onMainThread: #selector(updateJumpBtn), with: self, waitUntilDone: true) sleep(1); } } @objc func updateJumpBtn() { if (limitTime <= 0) { jumpBut.setTitle("跳过", for: .normal); } else { jumpBut.setTitle("跳过" + "(\(limitTime)S)", for: .normal); } } }

计时方式二(sleep + GCD)

与上面的方式一类似

// MARK: 定时方式二 func startCountDown() { // 将任务添加到队列,以异步的方式执行 DispatchQueue.global().async { [weak self] in self?.countDownThread(); } } func countDownThread() { let timeCount = limitTime; for _ in 0..<timeCount { limitTime = limitTime - 1; // 主线程刷新UI DispatchQueue.main.async { [weak self] in self?.updateJumpBtn(); } sleep(1); } } func updateJumpBtn() { if (limitTime <= 0) { jumpBut.setTitle("跳过", for: .normal); } else { jumpBut.setTitle("跳过" + "(\(limitTime)S)", for: .normal); } }

计时方式三(Timer)

// MARK: 定时方式三 var limitTime: Int = 5; var timer: Timer?; func startCountDown() { // 初始化定时器 timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateJumpBtn), userInfo: nil, repeats: true); } @objc func countDownThread() { // 主线程刷新UI DispatchQueue.main.async { [weak self] in self?.updateJumpBtn(); } } @objc func updateJumpBtn() { limitTime = limitTime - 1; if (limitTime <= 0) { jumpBut.setTitle("跳过", for: .normal); // 停止定时器 timer?.invalidate(); } else { jumpBut.setTitle("跳过" + "(\(limitTime)S)", for: .normal); } }

计时方式四(GCD)

// MARK: 定时方式四 var limitTime: Int = 5+1; // 在global线程里创建一个时间源 let codeTimer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()); func startCountDown() { // 设定这个时间源是每秒循环一次,立即开始 codeTimer.schedule(deadline: .now(), repeating: .seconds(1)); // 设定时间源的触发事件 codeTimer.setEventHandler(handler: { // 主线程刷新UI DispatchQueue.main.async { [weak self] in self?.updateJumpBtn(); } }) // 判断是否取消,如果已经取消了避免调用resume()方法导致的崩溃 if codeTimer.isCancelled { return; } // 启动时间源 codeTimer.resume(); } func updateJumpBtn() { limitTime = limitTime - 1; if (limitTime <= 0) { jumpBut.setTitle("跳过", for: .normal); // 暂停计时。暂停之后,再次开始计时(startCountDown())接着上次暂停进行计时 codeTimer.suspend(); // 取消计时。取消之后,再次开始计时(startCountDown())不会再计时 //codeTimer.cancel(); } else { jumpBut.setTitle("跳过" + "(\(limitTime)S)", for: .normal); } }

示意图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章