一.前言

之前的文章iOS 在cell中使用倒计时的处理方法得到大量的支持, 在这先感谢大家的支持. 但是也收到不少人的回复表示不会用, 需要一一解答, 由于之前写的时候没有使用Markdown编辑, 所以现在没法更新之前的文章, 重新写一份清晰的文章

需求: 每条Cell中显示倒计时, 并随时间进行倒数
语言: Objective-C & Swift
系统: iOS
Github地址: OYCountDownManager v2.0
OYCountDownManager-Swift v2.0

二.原理分析

 
原理分析图.png
 
单个列表倒计时.gif

v2.0新增

* 多个列表倒计时
* 多个页面倒计时
* 分页列表倒计时
* 后台模式倒计时
 
多个列表倒计时.gif
 
多个页面倒计时.gif
 
分页列表倒计时.gif

三.使用方法

1.1 第一种方法: 使用cocoapods自动安装

pod 'OYCountDownManager'

1.2 第二种方法

下载示例Demo, 把里面的OYCountDownManager文件夹拖到你的项目中

2. 在第一次使用的地方调用[kCountDownManager start]

- (void)viewDidLoad {
[super viewDidLoad]; // 启动倒计时管理
[kCountDownManager start];
}

3. 在Cell初始化中监听通知 kCountDownNotification

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
// 监听通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(countDownNotification) name:kCountDownNotification object:nil];
}
return self;
}

4. 在cell设置通知回调, 取得时间差, 根据时间差进行处理

- (void)countDownNotification {
/// 计算倒计时
NSInteger countDown = [self.model.count integerValue] - kCountDownManager.timeInterval;
if (countDown <= ) {
// 倒计时结束时回调
xxxx(使用代理或block)
}return;
/// 重新赋值
self.timeLabel.text = [NSString stringWithFormat:@"倒计时%02zd:%02zd:%02zd", countDown/, (countDown/)%, countDown%];
}

5. 当刷新数据时,调用reload方法

- (void)reloadData {
// 网络加载数据 // 调用[kCountDownManager reload]
[kCountDownManager reload];
// 刷新
[self.tableView reloadData];
}

6. 当不需要倒计时时, 废除定时器

[kCountDownManager invalidate];

四.高级使用(多列表.多页面.分页列表)

增加identifier:标识符, 一个identifier支持一个倒计时源, 有一个单独的时间差

/** 添加倒计时源 */
- (void)addSourceWithIdentifier:(NSString *)identifier; /** 获取时间差 */
- (NSInteger)timeIntervalWithIdentifier:(NSString *)identifier; /** 刷新倒计时源 */
- (void)reloadSourceWithIdentifier:(NSString *)identifier; /** 刷新所有倒计时源 */
- (void)reloadAllSource; /** 清除倒计时源 */
- (void)removeSourceWithIdentifier:(NSString *)identifier; /** 清除所有倒计时源 */
- (void)removeAllSource;

以一个页面有两个独立的列表为例

1.定义identifier(常量)

NSString *const OYMultipleTableSource1 = @"OYMultipleTableSource1";
NSString *const OYMultipleTableSource2 = @"OYMultipleTableSource2";

2.增加倒计时源

// 增加倒计时源
[kCountDownManager addSourceWithIdentifier:OYMultipleTableSource1];
[kCountDownManager addSourceWithIdentifier:OYMultipleTableSource2];

3.在cell通知回调中, 通过identifier取得时间差, 根据时间差进行处理

- (void)countDownNotification {
/// 判断是否需要倒计时 -- 可能有的cell不需要倒计时,根据真实需求来进行判断
if () {
return;
}
/// 计算倒计时
OYModel *model = self.model;
/// 根据identifier取得时间差, 以OYMultipleTableSource1为例
NSInteger timeInterval = timeInterval = [kCountDownManager timeIntervalWithIdentifier: OYMultipleTableSource1];
}
NSInteger countDown = model.count - timeInterval;
/// 当倒计时到了进行回调
if (countDown <= ) {
self.detailTextLabel.text = @"活动开始";
// 倒计时结束时回调
xxxx(使用代理或block)
return;
}
/// 重新赋值
self.detailTextLabel.text = [NSString stringWithFormat:@"倒计时%02zd:%02zd:%02zd", countDown/, (countDown/)%, countDown%];
}

4. 当刷新数据时,调用reloadSourceWithIdentifier:刷新时间差

- (void)reloadData {
// 网络加载数据 // 调用reloadSourceWithIdentifier:刷新时间差
[kCountDownManager reloadSourceWithIdentifier:OYMultiplePageSource1];
// 刷新
[self.tableView reloadData];
}

5. 当页面销毁, 移除倒计时源, 或者不需要定时器, 废除定时器

- (void)reloadData {
// 网络加载数据 // 调用reloadSourceWithIdentifier:刷新时间差
[kCountDownManager reloadSourceWithIdentifier:OYMultiplePageSource1];
// 刷新
[self.tableView reloadData];
}

五.注意事项

误差分析

  • NSTimer可以精确到50-100毫秒,不是绝对准确的,所以使用时间累加的方法时间久了有可能成为时间误差的来源
  • 为秒为单位触发定时器, 当reloadData后, 定时器也许刚好到达触发点, 时间差+1, 数据刚reload完就马上-1秒
  • 后台模式是以进入后台的本地时间, 及进入前台的本地时间做差值来计算的, 当用户手动修改本地时间, 也会成为时间差错误的来源之一, 如果能在进入前台的时间再从服务器取一次数据, 或者记录服务器时间而不是本地时间, 也可以避免这一误差

滚动cell时出去文字闪烁

在给cell的模型赋值后, 最好手动调用一下countDownNotification方法, 保证及时刷新

///  重写setter方法
- (void)setModel:(Model *)model {
_model = model;
self.titleLabel.text = model.title;
// 手动调用通知的回调
[self countDownNotification];
}

倒计时为0后出现复用问题

在倒计时为0后, 应该回调给控制器, 从后台请求一次数据, 保证倒计时没有出现误差

if (countDown <= ) {
// 倒计时结束时回调
xxxx(使用代理或block)
}return;

出现每秒倒计时减2的问题

1.查看定时器设置是否正确, 或者通知是否监听了两次
2.在countDownNotification方法中, 是否用[NSDate date]做了某些计算, 因为[NSDate date]为当前时间, 每一秒去取都会比上一秒大一秒, 再加上timeInterval也是一秒加一, 那么就会出现每秒倒计时减2的问题

如果还有不懂的问题, 或者出现其它bug
请查看Demo: Demo
或者给我留言, 喜欢的话, 就给作者一个star

作者:大头herob
链接:https://www.jianshu.com/p/af62a56ef7e2
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 
 
 

iOS 在cell中使用倒计时的处理方法(新)的更多相关文章

  1. iOS:在cell中使用倒计时的最佳方法

    一.简单介绍 在UITableViewCell中每条数据中显示该内容的倒计时, 并随时间进行倒数,这是很多电商app最常见的活动推销功能模块,自然想到用的就是计时器了. 二.基本想法 想法1:在每个c ...

  2. iOS去掉字符串中的HTML标签的方法

    方法一.NSScanner去除标签 - (NSString *)removeTheHtmlFromString:(NSString *)htmlString { NSScanner * scanner ...

  3. iOS 之项目中遇到的问题总结

    昨天去一家公司面试,面试官问了我在项目开发中遇到过哪些问题,是什么引起的,怎样解决的? 当时由于有点小紧张只说出了一两点,现在就来好好总结一下. 问题: 1.两表联动 所谓的两表联动就是有左右两个表格 ...

  4. [每天记录一个Bug]Cell中由于block加载网络请求产生的复用

    Bug 出现场景:   cell中使用加载图片的网络请求出现复用,截图如下:         复用原因:   Cell Model中只有一个用户的uid,所有用户相关信息:例如头像\名称\信息等是通过 ...

  5. iOS UIAlertController中加入倒计时,输入框,Swift讲解

    一.倒计时 @interface ViewController () { UIAlertController *alertview; NSString * message; NSTimer * wai ...

  6. iOS学习——tableview中带编辑功能的cell键盘弹出遮挡和收起问题解决

    最近在项目中经常用到UITableView中的cell中带有UITextField或UITextView的情况,然后在这种场景下,当我们点击屏幕较下方的cell进行编辑时,这时候键盘弹出来会出现遮挡待 ...

  7. iOS中获取cell中webview的内容尺寸

    最近项目中遇到在cell中获取webView的内容的尺寸的需求 实现的思路其实很简单 就是通过执行js 获取尺寸即可 为了后面用着方便我直接封装了一个HTML的cell 起名就叫 STHTMLBase ...

  8. iOS之UITableView中的cell因为重用机制导致新的cell的数据出现重复或者错乱

      UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚 ...

  9. iOS:一个Cell中设置另外一个Cell中的button

    场景: 子类化Cell中有button,拥有选中式样,点击第一个Cell中的button后,Cell一中的button获得选中式样.可是当点击Cell二中的button时.Cell一中的button选 ...

随机推荐

  1. 8148 add spi driver

    http://blog.csdn.net/zouwen198317/article/details/8452209 http://e2e.ti.com/support/dsp/davinci_digi ...

  2. QT软件初次使用中遇到的若干问题及思考

    1.QT窗口名称汉字设置问题? 答案:在MSVC中试用诸多方法,亲测都不行. 解决方案1:创建项目时,选择使用MSGW方案,用gcc进行编译,即可解决 2.QT中ui文件中组件不能再.cpp文件中显示 ...

  3. bootstrap基础学习十篇

    bootstrap字体图标(Glyphicons) a.什么是字体图标 字体图标是在 Web 项目中使用的图标字体.虽然,Glyphicons Halflings 需要商业许可,但是您可以通过基于项目 ...

  4. 第6步:检查grid安装环境

    6.1 检查系统包 grid 身份下校验安装环境(检测crs安装环境(sgdb1)) [root@node1 soft]#su – grid [grid@node1 ~]$ cd /soft/grid ...

  5. java获取系统时区

    //Calendar cal = Calendar.getInstance(); //TimeZone timeZone = cal.getTimeZone(); TimeZone timeZone ...

  6. java -Mac搭建本地服务器并映射到外网

    最近在学习Html,小有进步变想着写一个浪漫的静态页面给女朋友浪漫一下,那么问题就来了,如何把我的网页让对网络一窍不通的女朋友看到,所以便想到了是用自己电脑作为服务器的想法.百度以后整理如下: 首先搭 ...

  7. mvc jsonresult 前台、后台解析

    背景介绍:asp.net中使用json对象传参;mvc中可以直接使用jsonresult这个对象 一:怎么使用jsonresult public JsonResult text() { var str ...

  8. Blue Bird

    Blue Bird 哈巴他一 他拉 毛套拉那 一套一太(他)卖咋西他 闹哇 啊哦一 啊哦一 啊闹扫啦 卡那西米哇马达 哦包爱 啦来字赛次那撒哇姨妈 次卡米哈几卖他阿娜塔爱套一大 靠闹看叫毛姨妈靠逃吧你 ...

  9. 【IE兼容性】代码中多语言样式+IE不兼容解决

    一.代码中样式根据不同语言对IE做不兼容解决 二.代码逻辑: 1. 后台返回语言信息: result.addObject("language",getLocaleStr());   ...

  10. 【转】Spring MVC 3.x 基本配置

    WEB-INF/web.xml 例1 <?xml version="1.0" encoding="UTF-8"?> <web-app xmln ...