效果如下:

ViewController.h

 #import <UIKit/UIKit.h>

 @interface ViewController : UIViewController
@property (assign, nonatomic) NSInteger surplusSecond; @property (strong, nonatomic) IBOutlet UILabel *lblMessage;
@property (strong, nonatomic) IBOutlet UIButton *btnSendCAPTCHA; @end

ViewController.m

 #import "ViewController.h"

 @interface ViewController ()
- (void)layoutUI;
- (void)countDown;
@end @implementation ViewController
#define kSurplusSecond 5 - (void)viewDidLoad {
[super viewDidLoad]; [self layoutUI];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (void)layoutUI {
_surplusSecond = kSurplusSecond; //剩余秒数;这里指验证码发送完,间隔多少秒才能再次点击「验证」按钮进行发送验证码 _btnSendCAPTCHA.tintColor = [UIColor darkGrayColor];
_btnSendCAPTCHA.layer.masksToBounds = YES;
_btnSendCAPTCHA.layer.cornerRadius = 10.0;
_btnSendCAPTCHA.layer.borderColor = [UIColor grayColor].CGColor;
_btnSendCAPTCHA.layer.borderWidth = 1.0;
} /**
* 倒计时
*/
- (void)countDown {
//全局并发队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
//主队列;属于串行队列
dispatch_queue_t mainQueue = dispatch_get_main_queue(); //定时循环执行事件
//dispatch_source_set_timer 方法值得一提的是最后一个参数(leeway),他告诉系统我们需要计时器触发的精准程度。所有的计时器都不会保证100%精准,这个参数用来告诉系统你希望系统保证精准的努力程度。如果你希望一个计时器每5秒触发一次,并且越准越好,那么你传递0为参数。另外,如果是一个周期性任务,比如检查email,那么你会希望每10分钟检查一次,但是不用那么精准。所以你可以传入60,告诉系统60秒的误差是可接受的。他的意义在于降低资源消耗。
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, , , globalQueue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{ //计时器事件处理器
NSLog(@"Event Handler");
if (_surplusSecond <= ) {
dispatch_source_cancel(timer); //取消定时循环计时器;使得句柄被调用,即事件被执行
dispatch_async(mainQueue, ^{
_btnSendCAPTCHA.enabled = YES;
[_btnSendCAPTCHA setTitle:@"验证" forState:UIControlStateNormal]; _lblMessage.text = @"使用 GCD 实现倒计时效果";
_surplusSecond = kSurplusSecond;
});
} else {
_surplusSecond--;
dispatch_async(mainQueue, ^{
NSString *btnInfo = [NSString stringWithFormat:@"%ld秒", (long)(_surplusSecond + )];
_btnSendCAPTCHA.enabled = NO;
[_btnSendCAPTCHA setTitle:btnInfo forState:UIControlStateDisabled];
});
}
});
dispatch_source_set_cancel_handler(timer, ^{ //计时器取消处理器;调用 dispatch_source_cancel 时执行
NSLog(@"Cancel Handler");
});
dispatch_resume(timer); //恢复定时循环计时器;Dispatch Source 创建完后默认状态是挂起的,需要主动恢复,否则事件不会被传递,也不会被执行
} - (IBAction)sendCAPTCHA:(id)sender {
_lblMessage.text = [NSString stringWithFormat:@"验证码发送成功,%d秒后可重新发送", kSurplusSecond]; [self countDown];
} @end

Main.storyboard

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="ufC-wZ-h7g">
<objects>
<viewController id="vXZ-lx-hvc" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="使用 GCD 实现倒计时效果" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Kh-pV-cfz">
<rect key="frame" x="200" y="289.5" width="200" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rFe-Xb-ZSc">
<rect key="frame" x="240" y="510" width="120" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="gVH-aT-gen"/>
<constraint firstAttribute="height" constant="50" id="jJP-Vc-fpy"/>
</constraints>
<state key="normal" title="验证">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="sendCAPTCHA:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="I6T-s9-9H6"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="rFe-Xb-ZSc" secondAttribute="centerX" id="CoE-CP-eDN"/>
<constraint firstAttribute="centerY" secondItem="1Kh-pV-cfz" secondAttribute="centerY" id="bX4-jS-0xm"/>
<constraint firstAttribute="centerX" secondItem="1Kh-pV-cfz" secondAttribute="centerX" id="mKH-Zw-Utb"/>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" secondItem="rFe-Xb-ZSc" secondAttribute="bottom" constant="40" id="y3Q-IA-qIO"/>
</constraints>
</view>
<connections>
<outlet property="btnSendCAPTCHA" destination="rFe-Xb-ZSc" id="UFG-TS-ImX"/>
<outlet property="lblMessage" destination="1Kh-pV-cfz" id="gzx-3T-euc"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

输出结果:

 -- ::02.083 KMCountDown[:] Event Handler
-- ::03.087 KMCountDown[:] Event Handler
-- ::04.084 KMCountDown[:] Event Handler
-- ::05.086 KMCountDown[:] Event Handler
-- ::06.085 KMCountDown[:] Event Handler
-- ::07.085 KMCountDown[:] Event Handler
-- ::07.085 KMCountDown[:] Cancel Handler

使用 GCD 实现倒计时效果的更多相关文章

  1. iOS 使用GCD实现倒计时效果

    在APP开发过程中,经常有需要实现倒计时效果, 比如语音验证码倒计时...代码如下: __block int timeout = 100; dispatch_queue_t queue = dispa ...

  2. Andorid实现点击获取验证码倒计时效果

    这篇文章主要介绍了Andorid实现点击获取验证码倒计时效果,这种效果大家经常遇到,想知道如何实现的,请阅读本文   我们在开发中经常用到倒计时的功能,比如发送验证码后,倒计时60s再进行验证码的获取 ...

  3. jQuery Countdown Timer 倒计时效果

    这个一款简单的 jQuery 倒计时插件,用于显示剩余的天数,小时,分钟和秒.倒计时功能是非常有用的一个小功能,可以告诉用户多久以后您的网站将会发布或者关闭进行维护,还可以用于举办活动的开始和停止的倒 ...

  4. js实现倒计时效果

    <!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/htm ...

  5. 二、JavaScript语言--JS实践--倒计时效果

    主要内容:分析不同倒计时效果的计算思路及方法,掌握日期对象Date,获取时间的方法,计算时差的方法,实现不同的倒时计效果. Javascript 日期对象: Date()返回当前的日期和时间 getY ...

  6. javascript特效实现(4)——当前时间和倒计时效果

    这个效果的实现关键是对Date对象和setTimeout的使用. 一共有三个例子,HTML结构如下,就不添加CSS样式了. <body> 当前时间:<p id="p1&qu ...

  7. 超实用的JavaScript代码段 --倒计时效果

    现今团购网.电商网.门户网等,常使用时间记录重要的时刻,如时间显示.倒计时差.限时抢购等,本文分析不同倒计时效果的计算思路及方法,掌握日期对象Date,获取时间的方法,计算时差的方法,实现不同的倒时计 ...

  8. jquery网页倒计时效果,秒杀,限时抢购!

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. [jQuery编程挑战]006 生成一个倒计时效果

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8&quo ...

随机推荐

  1. jd-gui的使用方法

    java的反编译工具,简单使用: 打开文件.单击“file”从中选择“Open File ...“选项,弹出一个文件选择框,可以选择要打开的文件,或者直接单击文件夹图标,直接弹出文件选择框:从文件选择 ...

  2. Android Developers:传感器概述

    大 多数Android设备有内置的传感器,来测量运动,方向和各种环境条件.这些传感器能提供高精度和准确度的原始数据,如果你想监控设备三维运动或者位 置,或者你想监控设备周围的环境变化,是非常有用的.例 ...

  3. HTML篇之CSS样式:<button></button>按钮变成超链接<a></a>的样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Maven deploy部署jar到远程私服仓库

    一.配置私服账号密码 修改maven配置文件,在$MAVEN_HOME/conf/setting.xml中增加如下配置: 注意,这里配置的id为releases何snapshots,当然可以改为其他, ...

  5. Word批量删除所有书签

    Word中的书签功能可快速.准确定位文档中特定的位置,经常用于模板定制.文档产出等. 可一直以来,书签功能存在一个不便的操作,即无法批量删除,只能单个删除,操作极不友好. 解决方案 我用代码暂时还改变 ...

  6. shell编程学习笔记(二):Shell中变量的使用

    变量在很多编程语言中都有,Shell中也不例外,我们下面看一下Shell中的变量怎么使用: 以下蓝色字体部分为Linux命令,红色字体的内容为输出的内容: # cd /opt/scripts # vi ...

  7. 〖Android〗从Android Studio转为Eclipse开发项目运行程序闪退的解决方法

    很久没有撸Android App开发了- 最近把一个月前通过反编译.二次修改的Android SSHD项目进行简单修改一下: 突然发现迁移项目时,报了一个错误,同时还出现了闪退情况: - ::): t ...

  8. B+树索引和哈希索引的区别[转]

    导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...

  9. 多分类-- ROC曲线

    本文主要介绍一下多分类下的ROC曲线绘制和AUC计算,并以鸢尾花数据为例,简单用python进行一下说明.如果对ROC和AUC二分类下的概念不是很了解,可以先参考下这篇文章:http://blog.c ...

  10. SNF快速开发平台WinForm-CS甘特图

    我们在做项目当中会经常用到按时间进度查看任务,其通过条状图来显示项目,进度,和其他时间相关的系统进展的内在关系随着时间进展的情况. 甘特图包含以下三个含义: 1.以图形或表格的形式显示活动: 2.通用 ...