Swift實現(xiàn)倒計時5秒功能
一般在項目的“引導(dǎo)頁”有個功能,倒計時5秒結(jié)束后,然后可以允許用戶點擊跳過按鈕跳過引導(dǎo)頁。同樣在“登錄”和“注冊”頁面也有類似功能,發(fā)送驗證碼后,計時60秒后才允許用戶再次請求重新發(fā)送驗證碼。
計時方式一(sleep + performSelector)
通過調(diào)用sleep(1)阻塞線程的方式來達(dá)到目的
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() {
// 將任務(wù)添加到隊列,以異步的方式執(zhí)行
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;
// 繼續(xù)定時
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線程里創(chuàng)建一個時間源
let codeTimer = DispatchSource.makeTimerSource(queue: DispatchQueue.global());
func startCountDown() {
// 設(shè)定這個時間源是每秒循環(huán)一次,立即開始
codeTimer.schedule(deadline: .now(), repeating: .seconds(1));
// 設(shè)定時間源的觸發(fā)事件
codeTimer.setEventHandler(handler: {
// 主線程刷新UI
DispatchQueue.main.async { [weak self] in
self?.updateJumpBtn();
}
})
// 判斷是否取消,如果已經(jīng)取消了避免調(diào)用resume()方法導(dǎo)致的崩潰
if codeTimer.isCancelled {
return;
}
// 啟動時間源
codeTimer.resume();
}
func updateJumpBtn() {
limitTime = limitTime - 1;
if (limitTime <= 0) {
jumpBut.setTitle("跳過", for: .normal);
// 暫停計時。暫停之后,再次開始計時(startCountDown())接著上次暫停進(jìn)行計時
codeTimer.suspend();
// 取消計時。取消之后,再次開始計時(startCountDown())不會再計時
//codeTimer.cancel();
} else {
jumpBut.setTitle("跳過" + "(\(limitTime)S)", for: .normal);
}
}
示意圖

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Swift開發(fā)應(yīng)用中如何更方便地使用顏色詳解
這篇文章主要給大家介紹了關(guān)于Swift開發(fā)應(yīng)用中如何更方便地使用顏色的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
Compose聲明式代碼語法對比React?Flutter?SwiftUI
這篇文章主要為大家介紹了Compose聲明式代碼語法對比React?Flutter?SwiftUI來解釋為什么說?Compose?的聲明式代碼最簡潔,有需要的朋友可以借鑒參考下2022-08-08
Flutter iOS開發(fā)OC混編Swift動態(tài)庫和靜態(tài)庫問題填坑
這篇文章主要為大家介紹了Flutter iOS OC 混編 Swift動態(tài)庫和靜態(tài)庫問題填坑詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Swift下使用UICollectionView 實現(xiàn)長按拖拽功能
拖拽排序是新聞類的App可以說是必有的交互設(shè)計,如今日頭條,網(wǎng)易新聞等。這篇文章主要介紹了Swift下使用UICollectionView 長按拖拽功能,需要的朋友可以參考下2017-03-03
swift實現(xiàn)自定義圓環(huán)進(jìn)度提示效果
這篇文章主要為大家詳細(xì)介紹了swift實現(xiàn)自定義圓環(huán)進(jìn)度提示效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-05-05

