Swift實(shí)現(xiàn)倒計(jì)時(shí)5秒功能
一般在項(xiàng)目的“引導(dǎo)頁(yè)”有個(gè)功能,倒計(jì)時(shí)5秒結(jié)束后,然后可以允許用戶點(diǎn)擊跳過按鈕跳過引導(dǎo)頁(yè)。同樣在“登錄”和“注冊(cè)”頁(yè)面也有類似功能,發(fā)送驗(yàn)證碼后,計(jì)時(shí)60秒后才允許用戶再次請(qǐng)求重新發(fā)送驗(yàn)證碼。
計(jì)時(shí)方式一(sleep + performSelector)
通過調(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("跳過(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來(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實(shí)現(xiàn)一個(gè)響應(yīng)式編程庫(kù)
最近在學(xué)習(xí)swift,最近有空所以總結(jié)一下最近學(xué)習(xí)的內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于利用Swift實(shí)現(xiàn)一個(gè)響應(yīng)式編程庫(kù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-12-12
詳談swift內(nèi)存管理中的引用計(jì)數(shù)
下面小編就為大家?guī)?lái)一篇詳談swift內(nèi)存管理中的引用計(jì)數(shù)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-09-09
Swift 3.0將UILabel數(shù)字顏色設(shè)置為紅色的方法
這篇文章主要介紹了關(guān)于在Swift中將UILabel數(shù)字顏色設(shè)置為紅色的方法,文中給出了詳細(xì)的示例代碼,相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-03-03
Swift教程之基礎(chǔ)數(shù)據(jù)類型詳解
這篇文章主要介紹了Swift教程之基礎(chǔ)數(shù)據(jù)類型詳解,本文詳細(xì)講解了Swift中的基本數(shù)據(jù)類型和基本語(yǔ)法,例如常量和變量、注釋、分號(hào)、整數(shù)、數(shù)值類型轉(zhuǎn)換等內(nèi)容,需要的朋友可以參考下2015-01-01
swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑菜單功能的示例代碼
這篇文章主要介紹了swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑功能的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-06-06
通過Notification.Name看Swift是如何優(yōu)雅的解決String硬編碼
這篇文章主要給大家介紹了通過Notification.Name看Swift是如何優(yōu)雅的解決String硬編碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
蘋果公司編程語(yǔ)言Swift語(yǔ)言簡(jiǎn)介
這篇文章主要介紹了蘋果公司編程語(yǔ)言Swift語(yǔ)言簡(jiǎn)介,Swift 是一門新的編程語(yǔ)言,兼容Objective-C代碼,是用來(lái)代替Objective-C的蘋果主力開發(fā)語(yǔ)言,需要的朋友可以參考下2014-07-07

