iOS活动倒计时的两种实现方式
在做些活动界面或者限时验证码时, 经常会使用一些倒计时突出展现.

现提供两种方案:
一.使用NSTimer定时器来倒计时
二.使用GCD来倒计时(用GCD这个写有一个好处,跳页不会清零, 跳页清零会出现倒计时错误的)
压缩文件截图项目界面:

项目截图:

一. 使用NSTimer定时器来倒计时
主要步骤:
Step1. 计算截止时间与当前时间差
Step2. 先递减时间差 倒计时-1(总时间以秒来计算)
Step3. 给时分秒字符串通过递减过后的秒数,重新计算数值,并输出显示.
获取当天的字符串, 格式为年-月-日 时分秒:
/**
* 获取当天的字符串
*
* @return 格式为年-月-日 时分秒
*/
- (NSString *)getCurrentTimeyyyymmdd {
NSDate *now = [NSDate date];
NSDateFormatter *formatDay = [[NSDateFormatter alloc] init];
formatDay.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *dayStr = [formatDay stringFromDate:now];
return dayStr;
}
获取时间差值 截止时间-当前时间:
/**
* 获取时间差值 截止时间-当前时间
* nowDateStr : 当前时间
* deadlineStr : 截止时间
* @return 时间戳差值
*/
- (NSInteger)getDateDifferenceWithNowDateStr:(NSString*)nowDateStr deadlineStr:(NSString*)deadlineStr {
NSInteger timeDifference = 0;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yy-MM-dd HH:mm:ss"];
NSDate *nowDate = [formatter dateFromString:nowDateStr];
NSDate *deadline = [formatter dateFromString:deadlineStr];
NSTimeInterval oldTime = [nowDate timeIntervalSince1970];
NSTimeInterval newTime = [deadline timeIntervalSince1970];
timeDifference = newTime - oldTime;
return timeDifference;
}
Step1. 计算时间差值:
NSInteger secondsCountDown = [self getDateDifferenceWithNowDateStr:nowStr deadlineStr:deadlineStr];
Step2. 递减时间差 倒计时-1(总时间以秒来计算):
secondsCountDown--;
Step3.活动倒计时:
// 启动倒计时后会每秒钟调用一次方法
_activeTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(activeCountDownAction) userInfo:nil repeats:YES];
[_activeTimer fire];
给时分秒字符串通过递减过后的秒数,重新计算数值,并输出显示:
// 重新计算 时/分/秒
NSString *str_hour = [NSString stringWithFormat:@"%02ld", secondsCountDown / 3600];
NSString *str_minute = [NSString stringWithFormat:@"%02ld", (secondsCountDown % 3600) / 60];
NSString *str_second = [NSString stringWithFormat:@"%02ld", secondsCountDown % 60];
NSString *format_time = [NSString stringWithFormat:@"%@ : %@ : %@", str_hour, str_minute, str_second];
// 修改倒计时标签及显示内容
self.timeLabel.text = [NSString stringWithFormat:@"使用NSTimer来实现 活动倒计时: %@", format_time];
// 当倒计时结束时做需要的操作: 比如活动到期不能提交
if(secondsCountDown <= 0) {
self.timeLabel.text = @"当前活动已结束";
[_activeTimer invalidate];
_activeTimer = nil;
return;
}
NSTimer-活动倒计时测试效果如下:

二. 使用GCD来倒计时
主要步骤:
Step1. 计算截止时间与当前时间差
Step2. 用GCD倒计时 给时分秒字符串通过递减过后的秒数,重新计算数值,并输出显示, 递减时间差 倒计时-1
Step1. 计算截止时间与当前时间差:
// 倒计时的时间 测试数据
NSString *deadlineStr = @"2017-08-19 12:00:00";
// 当前时间的时间戳
NSString *nowStr = [self getCurrentTimeyyyymmdd];
// 计算时间差值
NSInteger secondsCountDown = [self getDateDifferenceWithNowDateStr:nowStr deadlineStr:deadlineStr];
Step2.使用GCD来实现倒计时
用GCD这个写有一个好处,跳页不会清零 跳页清零会出现倒计时错误的
活动结束等逻辑及界面处理可以按照自己需求来~
__weak __typeof(self) weakSelf = self;
if (_timer == nil) {
__block NSInteger timeout = secondsCountDown; // 倒计时时间
if (timeout!=0) {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0*NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout <= 0){ // 当倒计时结束时做需要的操作: 关闭 活动到期不能提交
dispatch_source_cancel(_timer);
_timer = nil;
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.timeLabel.text = @"当前活动已结束";
});
} else { // 倒计时重新计算 时/分/秒
NSInteger days = (int)(timeout/(3600*24));
NSInteger hours = (int)((timeout-days*24*3600)/3600);
NSInteger minute = (int)(timeout-days*24*3600-hours*3600)/60;
NSInteger second = timeout - days*24*3600 - hours*3600 - minute*60;
NSString *strTime = [NSString stringWithFormat:@"活动倒计时 %02ld : %02ld : %02ld", hours, minute, second];
dispatch_async(dispatch_get_main_queue(), ^{
if (days == 0) {
weakSelf.timeLabel.text = strTime;
} else {
weakSelf.timeLabel.text = [NSString stringWithFormat:@"使用GCD来实现活动倒计时 %ld天 %02ld : %02ld : %02ld", days, hours, minute, second];
}
});
timeout--; // 递减 倒计时-1(总时间以秒来计算)
}
});
dispatch_resume(_timer);
}
}
GCD-活动倒计时测试效果如下:
iOS活动倒计时的两种实现方式
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
iOS活动倒计时的两种实现方式的更多相关文章
- ios实现倒计时的两种方法
方法1:使用NSTimer来实现 主要使用的是NSTimer的scheduledTimerWithTimeInterval方法来每1秒执行一次timeFireMethod函数,timeFireMeth ...
- IOS文件操作的两种方式:NSFileManager操作和流操作
1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...
- iOS单例的两种实现
单例模式算是开发中比较常见的一种模式了.在iOS中,单例有两种实现方式(至少我目前只发现两种).根据线程安全的实现来区分,一种是使用@synchronized,另一种是使用GCD的dispatch_o ...
- Android四大组件之服务的两种启动方式详解
Service简单概述 Service(服务):是一个没有用户界面.可以在后台长期运行且可以执行操作的应用组件.服务可由其他应用组件启动(如:Activity.另一个service).此外,组件可以绑 ...
- Web APi之认证(Authentication)两种实现方式【二】(十三)
前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...
- Android中BroadcastReceiver的两种注册方式(静态和动态)详解
今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...
- Android中Fragment与Activity之间的交互(两种实现方式)
(未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...
- JavaScript 函数的两种声明方式
1.函数声明的方式 JavaScript声明函数有两种选择:函数声明法,表达式定义法. 函数声明法 function sum (num1 ,num2){ return num1+num2 } 表达式定 ...
- Redis两种持久化方式(RDB&AOF)
爬虫和转载请注明原文地址;博客园蜗牛:http://www.cnblogs.com/tdws/p/5754706.html Redis所需内存 超过可用内存怎么办 Redis修改数据多线程并发—Red ...
随机推荐
- Redux-react connect 源码自己重写
import Counter from '../components/Counter'; import { increment, decrement, incrementIfOdd, incremen ...
- smail修改字符串 汉字
韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 将smali文件中的unicode字符串变为汉字
- [CODECHEF]RIN
题意:一个人要在$m$个学期上$n$节课,在第$j$学期上$i$课有$X_{i,j}$的收益,有些课$B_i$有前置课程$A_i$,问最大得分 这个题我都做不出来还去看题解...我退役吧== 考虑每种 ...
- 计算gcd Exercise07_14
import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:计算gcd * */ public class Exercise07_14 ...
- keytool工具生成自签名证书并且通过浏览器导入证书
1.生成服务器证书库 keytool -genkey -alias tomcat -keypass changeit -keyalg RSA -keysize 1024 -validity 365 - ...
- 基于tiny4412的Linux内核移植 -- DM9621NP网卡驱动移植(四)
作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...
- 课程学习:Linux系统管理
版本 内核版本 发行版本 常见Linux发行版本 ubuntu: 易用,可靠:技术支持付费,生态稍弱 debin: 精简,稳定,可靠; 更新较慢, 无技术支持,软件过时, 企业不太用 opensuse ...
- vs code 使用Git进行源代码管理
第一步:用vs code 打开一个空文件夹,如本示例Demo2, 第二步:点击左侧第三个图标“源代码管理”,然后再点击初始化存储库按钮 初始化之后界面现变成下图所示: 此时文件夹中会新增一个隐藏文件夹 ...
- 关于Android架构那些事
刚开始,因为业务比较赶,我们也没有进行比较好的顶层设计,对代码的要求也是最低要求——完成功能开发就行了.这种短期设计也就造成了我们代码的扩展性几乎为零,稍微添加一点新功能,都要大动干戈.在后台系统架构 ...
- OpenCV平面物体检测
平面物体检测 这个教程的目标是学习如何使用 features2d 和 calib3d 模块来检测场景中的已知平面物体. 测试数据: 数据图像文件,比如 “box.png”或者“box_in_scene ...