Swift實(shí)現(xiàn)倒計(jì)時(shí)5秒功能
一般在項(xiàng)目的“引導(dǎo)頁”有個(gè)功能,倒計(jì)時(shí)5秒結(jié)束后,然后可以允許用戶點(diǎn)擊跳過按鈕跳過引導(dǎo)頁。同樣在“登錄”和“注冊(cè)”頁面也有類似功能,發(fā)送驗(yàn)證碼后,計(jì)時(shí)60秒后才允許用戶再次請(qǐng)求重新發(fā)送驗(yàn)證碼。
計(jì)時(shí)方式一(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("點(diǎn)擊“跳過”"); } } // MARK: 定時(shí)方式一 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); } } }
計(jì)時(shí)方式二(sleep + GCD)
與上面的方式一類似
// MARK: 定時(shí)方式二 func startCountDown() { // 將任務(wù)添加到隊(duì)列,以異步的方式執(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); } }
計(jì)時(shí)方式三(Timer)
// MARK: 定時(shí)方式三 var limitTime: Int = 5; var timer: Timer?; func startCountDown() { // 初始化定時(shí)器 timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateJumpBtn), userInfo: nil, repeats: true); /* // 避免timer在列表時(shí),滑動(dòng)時(shí)timer會(huì)暫停。 將timer放在另外一個(gè)線程中,然后開啟這個(gè)線程的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); /* // 暫停定時(shí)器 timer?.fireDate = Date.distantFuture; // 繼續(xù)定時(shí) timer?.fireDate = NSDate.init() as Date; // 暫停定時(shí)器3秒 timer?.fireDate = Date.init(timeIntervalSinceNow: 3.0); */ // 停止定時(shí)器 timer?.invalidate(); } else { jumpBut.setTitle("跳過" + "(\(limitTime)S)", for: .normal); } }
計(jì)時(shí)方式四(GCD)
// MARK: 定時(shí)方式四 var limitTime: Int = 5+1; // 在global線程里創(chuàng)建一個(gè)時(shí)間源 let codeTimer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()); func startCountDown() { // 設(shè)定這個(gè)時(shí)間源是每秒循環(huán)一次,立即開始 codeTimer.schedule(deadline: .now(), repeating: .seconds(1)); // 設(shè)定時(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; } // 啟動(dòng)時(shí)間源 codeTimer.resume(); } func updateJumpBtn() { limitTime = limitTime - 1; if (limitTime <= 0) { jumpBut.setTitle("跳過", for: .normal); // 暫停計(jì)時(shí)。暫停之后,再次開始計(jì)時(shí)(startCountDown())接著上次暫停進(jìn)行計(jì)時(shí) codeTimer.suspend(); // 取消計(jì)時(shí)。取消之后,再次開始計(jì)時(shí)(startCountDown())不會(huì)再計(jì)時(shí) //codeTimer.cancel(); } else { jumpBut.setTitle("跳過" + "(\(limitTime)S)", for: .normal); } }
示意圖
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Swift調(diào)用Objective-C編寫的API實(shí)例
- swift5.3 UIColor使用十六進(jìn)制顏色的方法實(shí)例
- 詳解Swift 結(jié)構(gòu)體
- Swift 進(jìn)階 —— map 和 flatMap的使用
- Swift 5.1 之類型轉(zhuǎn)換與模式匹配的教程詳解
- 如何使用Swift來實(shí)現(xiàn)一個(gè)命令行工具的方法
- Swift4使用GCD實(shí)現(xiàn)計(jì)時(shí)器
- Swift實(shí)現(xiàn)3D輪播圖效果
- Swift 中如何使用 Option Pattern 改善可選項(xiàng)的 API 設(shè)計(jì)
相關(guān)文章
Swift開發(fā)應(yīng)用中如何更方便地使用顏色詳解
這篇文章主要給大家介紹了關(guān)于Swift開發(fā)應(yīng)用中如何更方便地使用顏色的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03Compose聲明式代碼語法對(duì)比React?Flutter?SwiftUI
這篇文章主要為大家介紹了Compose聲明式代碼語法對(duì)比React?Flutter?SwiftUI來解釋為什么說?Compose?的聲明式代碼最簡(jiǎn)潔,有需要的朋友可以借鑒參考下2022-08-08Flutter iOS開發(fā)OC混編Swift動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)問題填坑
這篇文章主要為大家介紹了Flutter iOS OC 混編 Swift動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)問題填坑詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07swift4.2實(shí)現(xiàn)新聞首頁導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了swift4.2實(shí)現(xiàn)新聞首頁導(dǎo)航,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Swift下使用UICollectionView 實(shí)現(xiàn)長(zhǎng)按拖拽功能
拖拽排序是新聞?lì)惖腁pp可以說是必有的交互設(shè)計(jì),如今日頭條,網(wǎng)易新聞等。這篇文章主要介紹了Swift下使用UICollectionView 長(zhǎng)按拖拽功能,需要的朋友可以參考下2017-03-03swift實(shí)現(xiàn)自定義圓環(huán)進(jìn)度提示效果
這篇文章主要為大家詳細(xì)介紹了swift實(shí)現(xiàn)自定義圓環(huán)進(jìn)度提示效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05