以前的文章iOS 在cell中使用倒计时的处理方法获得大量的支持, 在这先感谢你们的支持. 可是也收到很多人的回复表示不会用, 须要一一解答, 因为以前写的时候没有使用Markdown编辑, 因此如今无法更新以前的文章, 从新写一份清晰的文章git
需求: 每条Cell中显示倒计时, 并随时间进行倒数
语言: Objective-C & Swift
系统: iOS
Github地址: OYCountDownManager v2.0
OYCountDownManager-Swift v2.0github
* 多个列表倒计时 * 多个页面倒计时 * 分页列表倒计时 * 后台模式倒计时
pod 'OYCountDownManager'
下载示例Demo, 把里面的OYCountDownManager文件夹拖到你的项目中
- (void)viewDidLoad { [super viewDidLoad]; // 启动倒计时管理 [kCountDownManager start]; }
- (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; }
- (void)countDownNotification { /// 计算倒计时 NSInteger countDown = [self.model.count integerValue] - kCountDownManager.timeInterval; if (countDown <= 0) { // 倒计时结束时回调 xxxx(使用代理或block) }return; /// 从新赋值 self.timeLabel.text = [NSString stringWithFormat:@"倒计时%02zd:%02zd:%02zd", countDown/3600, (countDown/60)%60, countDown%60]; }
- (void)reloadData { // 网络加载数据 // 调用[kCountDownManager reload] [kCountDownManager reload]; // 刷新 [self.tableView reloadData]; }
[kCountDownManager invalidate];
增长identifier:标识符, 一个identifier支持一个倒计时源, 有一个单独的时间差服务器
/** 添加倒计时源 */ - (void)addSourceWithIdentifier:(NSString *)identifier; /** 获取时间差 */ - (NSInteger)timeIntervalWithIdentifier:(NSString *)identifier; /** 刷新倒计时源 */ - (void)reloadSourceWithIdentifier:(NSString *)identifier; /** 刷新全部倒计时源 */ - (void)reloadAllSource; /** 清除倒计时源 */ - (void)removeSourceWithIdentifier:(NSString *)identifier; /** 清除全部倒计时源 */ - (void)removeAllSource;
以一个页面有两个独立的列表为例网络
NSString *const OYMultipleTableSource1 = @"OYMultipleTableSource1"; NSString *const OYMultipleTableSource2 = @"OYMultipleTableSource2";
// 增长倒计时源 [kCountDownManager addSourceWithIdentifier:OYMultipleTableSource1]; [kCountDownManager addSourceWithIdentifier:OYMultipleTableSource2];
- (void)countDownNotification { /// 判断是否须要倒计时 -- 可能有的cell不须要倒计时,根据真实需求来进行判断 if (0) { return; } /// 计算倒计时 OYModel *model = self.model; /// 根据identifier取得时间差, 以OYMultipleTableSource1为例 NSInteger timeInterval = timeInterval = [kCountDownManager timeIntervalWithIdentifier: OYMultipleTableSource1]; } NSInteger countDown = model.count - timeInterval; /// 当倒计时到了进行回调 if (countDown <= 0) { self.detailTextLabel.text = @"活动开始"; // 倒计时结束时回调 xxxx(使用代理或block) return; } /// 从新赋值 self.detailTextLabel.text = [NSString stringWithFormat:@"倒计时%02zd:%02zd:%02zd", countDown/3600, (countDown/60)%60, countDown%60]; }
- (void)reloadData { // 网络加载数据 // 调用reloadSourceWithIdentifier:刷新时间差 [kCountDownManager reloadSourceWithIdentifier:OYMultiplePageSource1]; // 刷新 [self.tableView reloadData]; }
- (void)reloadData { // 网络加载数据 // 调用reloadSourceWithIdentifier:刷新时间差 [kCountDownManager reloadSourceWithIdentifier:OYMultiplePageSource1]; // 刷新 [self.tableView reloadData]; }
偏差分析
滚动cell时出去文字闪烁
在给cell的模型赋值后, 最好手动调用一下countDownNotification方法, 保证及时刷新ide
/// 重写setter方法 - (void)setModel:(Model *)model { _model = model; self.titleLabel.text = model.title; // 手动调用通知的回调 [self countDownNotification]; }
倒计时为0后出现复用问题
在倒计时为0后, 应该回调给控制器, 从后台请求一次数据, 保证倒计时没有出现偏差spa
if (countDown <= 0) { // 倒计时结束时回调 xxxx(使用代理或block) }return;
出现每秒倒计时减2的问题
1.查看定时器设置是否正确, 或者通知是否监听了两次
2.在countDownNotification方法中, 是否用[NSDate date]作了某些计算, 由于[NSDate date]为当前时间, 每一秒去取都会比上一秒大一秒, 再加上timeInterval也是一秒加一, 那么就会出现每秒倒计时减2的问题3d
若是还有不懂的问题, 或者出现其它bug
请查看Demo: Demo
或者给我留言, 喜欢的话, 就给做者一个star代理