一.前言

之前的文章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. SQL Server 2008 SP3简体中文版官方下载

    微软日前公开发布了SQL Server 2008 SP3,用户可以从微软下载中心获取SP服务包和功能包升级.SP3主要包括自SQL Server 2008 SP2以来的累积更新,修复了用户反馈的一些问 ...

  2. MYSQL数据库连接

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  3. db2 sequence

    我的上两个专栏中已经介绍到了与版本 8 功能相关的主题.我们可能需要在今天设计的数据库和应用程序中考虑这些功能.我们已经谈论了新的数据分区的辅助索引和附加的索引修改.在上一期中,我们了解了 DSSIZ ...

  4. asp.net session丢失的解决方法小结

    现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: < sessionSt ...

  5. ext布局问题之tab panel内的gridpanel内容数据变多,出现滚动条

    1)解决之道: 1.修改tabPanel var tabs= new Ext.TabPanel({ border: false, region:'center', id:'center', activ ...

  6. VR应用开发遍地走的日子还有多远

    从上世纪60年代美国计算机科学家Ivan Sutherland发明的第一款真正意义上的虚拟现实头盔,到Facebook以20亿美元收购"虚拟现实之眼"Oculus Rift,大批厂 ...

  7. ajax 传递数组类型参数后台接收不到的问题

    在做排序功能的时候需要将一个数组的数据传递到后台,(当时怎么没用json,如果用json就没有那么多的事情了),数据提交采用ajax! 先看代码 js: submitbtn: function () ...

  8. 【BZOJ4384】[POI2015]Trzy wieże 树状数组

    [BZOJ4384][POI2015]Trzy wieże Description 给定一个长度为n的仅包含'B'.'C'.'S'三种字符的字符串,请找到最长的一段连续子串,使得这一段要么只有一种字符 ...

  9. shiro权限笔记

    shiro框架运行流程 认证:系统提供的用于识别用户身份的功能,通常就是登录功能.----让系统知道你是谁??授权:系统提供的为用户分配访问系统某些功能的能力.----让系统知道你能做什么?? 官网: ...

  10. 联想打字必须按FN+数字-fn打字

    对于联想G40.14英寸系列的本本,好多时候无意间可能把数字键锁定了. 这时候要做的是:打开运行--输入OSK--打开虚拟屏幕键盘.这时候可以找到 选项---打开数字键盘. 有时候某些电脑上没有NUM ...