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