项目中用到了tableView的多个cell倒计时问题,总结了两种方法:
1,在每一个cell中都添加一个定时器,计算剩余时间,然后实时刷新cell。由于cell的重利用机制,在viewController也加载一个定时器,然后遍历数据源计算剩余时间。
2,在viewController中开启一个定时器,然后遍历数据源计算剩余时间,然后刷新UITableView的visibleCells。
写了个demo,用了两种定时器(NSTimer和GCDTimer)来分别实现这两种方法,贴上地址以供下载,https://github.com/love1987/CellTimer。
这里主要说一下NSTimer实现的方法,要注意NSTimer受runloop的影响,防止tableVIew滚动的时候NSTimer停止工作,把NSTimer加到NSRunLoopCommonModes中;以及没有正确的释放NSTimer造成的内存泄漏问题,为防止NSTimer循环引用问题,类比iOS10提供的block方法,给NSTimer实现了一个block分类,已兼容更早的版本。
第一种方法:
viewController中更新数据源的核心代码
for(inti=0; i<30; i++) {
NSInteger temp =arc4random()%1000;
[self.array addObject:[NSNumber numberWithInteger:temp]];
}
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 block:^(NSTimer * _Nonnull timer) {
for (int i=0; i<weakSelf.array.count; i++) {
NSNumber*temp = weakSelf.array[i];
NSIntegertmp = temp.integerValue;
tmp--;
[weakSelf.array replaceObjectAtIndex:i withObject:[NSNumber numberWithInteger:tmp]];
}
}repeats:YES];
tableViewCell中的核心代码
- (void)configureTimerWithTime:(NSInteger)time {
_time= time;
if(self.timer) {
[self.timer invalidate];
self.timer=nil;
}
if(_time<=0) {
self.label.text=@"已结束";
return;
}
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 block:^(NSTimer * _Nonnull timer) {
if(weakSelf.time<=0) {
weakSelf.label.text=@"已结束";
[weakSelf.timer invalidate];
weakSelf.timer=nil;
return;
}
weakSelf.label.text= [NSString lessSecondToDay:weakSelf.time];;
weakSelf.time--;
}repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
[self.timer fire];
}
最后在viewController和tableViewCell中的dealloc中把timer销毁。
第二种方法:
viewController中的核心代码
for(inti=0; i<30; i++) {
NSInteger temp =arc4random()%1000;
[self.array addObject:[NSNumber numberWithInteger:temp]];
}
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 block:^(NSTimer * _Nonnull timer) {
for (int i=0; i<weakSelf.array.count; i++) {
NSNumber*temp = weakSelf.array[i];
NSInteger tmp = temp.integerValue;
tmp--;
[weakSelf.array replaceObjectAtIndex:i withObject:[NSNumber numberWithInteger:tmp]];
}
NSArray*cells = weakSelf.tableview.visibleCells;
for(VC_TimerTableViewCell*cellincells) {
NSNumber*temp = weakSelf.array[cell.tag];
NSInteger tmp = temp.integerValue;
[cell configureTimerWithTime:tmp];
}
}repeats:YES];
最后在viewController中的dealloc中把timer销毁。
网友评论