Swift实现倒计时5秒功能

 更新时间:2020年03月02日 09:11:47   作者:枫志应明  
这篇文章主要为大家详细介绍了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实现一个响应式编程库

    利用Swift实现一个响应式编程库

    最近在学习swift,最近有空所以总结一下最近学习的内容,下面这篇文章主要给大家介绍了关于利用Swift实现一个响应式编程库的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-12-12
  • Swift中非可选的可选值类型处理方法详解

    Swift中非可选的可选值类型处理方法详解

    Optional是Objective-C没有的数据类型,是苹果引入到Swift语言中的全新类型,它的特点就和它的名字一样:可以有值,也可以没有值,当它没有值时,就是nil。下面这篇文章主要给大家介绍了关于Swift中非可选的可选值类型处理方法的相关资料,需要的朋友可以参考下。
    2017-11-11
  • 详解Swift编程中的for循环的编写方法

    详解Swift编程中的for循环的编写方法

    这篇文章主要介绍了Swift编程中的for循环的编写方法,包括相关的for...in循环,需要的朋友可以参考下
    2015-11-11
  • 详谈swift内存管理中的引用计数

    详谈swift内存管理中的引用计数

    下面小编就为大家带来一篇详谈swift内存管理中的引用计数。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 程序迁移到swift 3.0的一些实用技巧

    程序迁移到swift 3.0的一些实用技巧

    Swift项目为适配iOS10,无奈只能更新Xcode 8 ,可是发现一入3.0深似海,从此幸福是路人。于是边摸索边修改,终于完成了代码迁移。节后在完成手头工作后,整理思路把Swift3.0迁移的一些实用技巧分享大家,需要的朋友可以参考下。
    2017-03-03
  • Swift 3.0将UILabel数字颜色设置为红色的方法

    Swift 3.0将UILabel数字颜色设置为红色的方法

    这篇文章主要介绍了关于在Swift中将UILabel数字颜色设置为红色的方法,文中给出了详细的示例代码,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • Swift教程之基础数据类型详解

    Swift教程之基础数据类型详解

    这篇文章主要介绍了Swift教程之基础数据类型详解,本文详细讲解了Swift中的基本数据类型和基本语法,例如常量和变量、注释、分号、整数、数值类型转换等内容,需要的朋友可以参考下
    2015-01-01
  • swift4 使用DrawerController实现侧滑菜单功能的示例代码

    swift4 使用DrawerController实现侧滑菜单功能的示例代码

    这篇文章主要介绍了swift4 使用DrawerController实现侧滑功能的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 通过Notification.Name看Swift是如何优雅的解决String硬编码

    通过Notification.Name看Swift是如何优雅的解决String硬编码

    这篇文章主要给大家介绍了通过Notification.Name看Swift是如何优雅的解决String硬编码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • 苹果公司编程语言Swift语言简介

    苹果公司编程语言Swift语言简介

    这篇文章主要介绍了苹果公司编程语言Swift语言简介,Swift 是一门新的编程语言,兼容Objective-C代码,是用来代替Objective-C的苹果主力开发语言,需要的朋友可以参考下
    2014-07-07

最新评论