Swift实现倒计时5秒功能

一般在项目的“引导页”有个功能,倒计时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);

/*

// 避免timer在列表时,滑动时timer会暂停。 将timer放在另外一个线程中,然后开启这个线程的runloop。

DispatchQueue.global().async { [weak self] in

self?.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self as Any, selector: #selector(self?.countDownThread), userInfo: nil, repeats: true);

RunLoop.current.run();

}

*/

}

@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?.fireDate = Date.distantFuture;

// 继续定时

timer?.fireDate = NSDate.init() as Date;

// 暂停定时器3秒

timer?.fireDate = Date.init(timeIntervalSinceNow: 3.0);

*/

// 停止定时器

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);

}

}

示意图

以上是 Swift实现倒计时5秒功能 的全部内容, 来源链接: utcz.com/z/361468.html

回到顶部