iOS中让多个cell上都出现倒计时的分析与实现

2020-01-20 23:38:49于海丽

前言

以前就有人问过这样一个问题:如果一个tableView的很多或者所有cell上都显示一个倒计时,该怎么实现? 今天自己恰好也遇到了这样的需求:很多产品,每个都有一个时限,在时限内才可以申购,过了申购功能就会关闭.简单描述就是,每个cell上有个倒计时,时间结束与否,点击cell响应的事件是不一样的.那么怎么实现呢?下面谈谈自己的思考过程.

1.Cell内部加一个定时器

既然每个cell都有一个倒计时,时间还可能不一样.根据"高内聚,低耦合"的思想,我首先想着直接让cell自己来实现倒计时功能:每个cell添加一个NSTimer,没隔1秒,让其显示的时间减少一秒.


- (void)timeChange {
 self.totalSeconds --;
 if (self.totalSeconds < 0) {
   self.timerLabel.text = @"倒计时结束";
  return;
 }
 self.timerLabel.text = [self timeChangeWithSeconds:self.totalSeconds];
}
- (void)setDataDict:(NSDictionary *)dataDict {
 _dataDict = dataDict;
 NSString *totalTime = dataDict[@"totalTime"];
 self.totalSeconds = totalTime.integerValue;
 self.timerLabel.text = [self timeChangeWithSeconds:self.totalSeconds];
 if (!_timer) {
  _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
  [[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];
 }
}
- (NSString*)timeChangeWithSeconds:(NSInteger)seconds {
 NSInteger temp1 = seconds/60;
 NSInteger temp2 = temp1/ 60;
 NSInteger d = temp2 / 24;
 NSInteger h = temp2 % 24;
 NSInteger m = temp1 % 60;
 NSInteger s = seconds %60;
 NSString * hour = h< 9 ? [NSString stringWithFormat:@"0%ld",(long)h] :[NSString stringWithFormat:@"%ld",(long)h];
 NSString *day = d < 9 ? [NSString stringWithFormat:@"0%ld",(long)d] : [NSString stringWithFormat:@"%ld",(long)d];
 NSString *minite = m < 9 ? [NSString stringWithFormat:@"0%ld",(long)m] : [NSString stringWithFormat:@"%ld",(long)m];
 NSString *second = s < 9 ? [NSString stringWithFormat:@"0%ld",(long)s] : [NSString stringWithFormat:@"%ld",(long)s];
 return [NSString stringWithFormat:@"%@天:%@时:%@分:%@秒",day,hour,minite,second];
}

ios,cell倒计时,cell中添加倒计时,cell,倒计时,重用

乍看,好像一切都OK,但是当我们拖动cell时,会发现一旦cell移除屏幕,再拖回来的时候,又会重头倒计时.当然,这和我在setDataDict:方法中的赋值方式有关,可以通过totalSeconds这个属性,保存当前剩余的时间,下一次再进来的时候,去取保存好的值.


- (void)setDataDict:(NSDictionary *)dataDict {
 _dataDict = dataDict;
  if (self.totalSeconds !=0) {
   self.timerLabel.text = [self timeChangeWithSeconds:self.totalSeconds];
 }else {
  NSString *totalTime = dataDict[@"totalTime"];
  self.totalSeconds = totalTime.integerValue;
  self.timerLabel.text = [self timeChangeWithSeconds:self.totalSeconds];
 }
  if (!_timer) {
  _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
  [[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];
 }
}