Swift實(shí)現(xiàn)倒計(jì)時(shí)5秒功能
一般在項(xiàng)目的“引導(dǎo)頁(yè)”有個(gè)功能,倒計(jì)時(shí)5秒結(jié)束后,然后可以允許用戶點(diǎn)擊跳過(guò)按鈕跳過(guò)引導(dǎo)頁(yè)。同樣在“登錄”和“注冊(cè)”頁(yè)面也有類似功能,發(fā)送驗(yàn)證碼后,計(jì)時(shí)60秒后才允許用戶再次請(qǐng)求重新發(fā)送驗(yàn)證碼。
計(jì)時(shí)方式一(sleep + performSelector)
通過(guò)調(diào)用sleep(1)阻塞線程的方式來(lái)達(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("跳過(guò)(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 == "跳過(guò)") { print("點(diǎn)擊“跳過(guò)”"); } } // 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("跳過(guò)", for: .normal); } else { jumpBut.setTitle("跳過(guò)" + "(\(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("跳過(guò)", for: .normal); } else { jumpBut.setTitle("跳過(guò)" + "(\(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è)線程中,然后開(kāi)啟這個(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("跳過(guò)", 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("跳過(guò)" + "(\(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)一次,立即開(kāi)始 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("跳過(guò)", for: .normal); // 暫停計(jì)時(shí)。暫停之后,再次開(kāi)始計(jì)時(shí)(startCountDown())接著上次暫停進(jìn)行計(jì)時(shí) codeTimer.suspend(); // 取消計(jì)時(shí)。取消之后,再次開(kāi)始計(jì)時(shí)(startCountDown())不會(huì)再計(jì)時(shí) //codeTimer.cancel(); } else { jumpBut.setTitle("跳過(guò)" + "(\(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來(lái)實(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開(kāi)發(fā)應(yīng)用中如何更方便地使用顏色詳解
這篇文章主要給大家介紹了關(guān)于Swift開(kāi)發(fā)應(yīng)用中如何更方便地使用顏色的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03Compose聲明式代碼語(yǔ)法對(duì)比React?Flutter?SwiftUI
這篇文章主要為大家介紹了Compose聲明式代碼語(yǔ)法對(duì)比React?Flutter?SwiftUI來(lái)解釋為什么說(shuō)?Compose?的聲明式代碼最簡(jiǎn)潔,有需要的朋友可以借鑒參考下2022-08-08Flutter iOS開(kāi)發(fā)OC混編Swift動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)問(wèn)題填坑
這篇文章主要為大家介紹了Flutter iOS OC 混編 Swift動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)問(wèn)題填坑詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07swift4.2實(shí)現(xiàn)新聞首頁(yè)導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了swift4.2實(shí)現(xiàn)新聞首頁(yè)導(dǎo)航,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Swift下使用UICollectionView 實(shí)現(xiàn)長(zhǎng)按拖拽功能
拖拽排序是新聞?lì)惖腁pp可以說(shuō)是必有的交互設(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