服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS中让多个cell上都出现倒计时的分析与实现

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

2021-03-22 16:35鲲鹏DP IOS

这篇文章主要给大家介绍了在iOS中每个cell上都出现倒计时的分析与实现,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。

前言

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

1.cell内部加一个定时器

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- (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上都出现倒计时的分析与实现

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (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];
 }
}

这样做,会发现当cell移除屏幕,再移回来的时候,不再是从头倒计时,但是多拖动几次又会发现新的问题:显示错乱,某个cell出现在了不该出现的位置.

仔细分析不难发现,cell的复用机制是引起上述现象的"罪魁祸首",要解决这个问题,可以让cell不复用,比方说,可以给每个cell绑定不同的标识,达到不复用的目的,看到这里,如果你也是这么想的,那么最好打住,因为为了达到这个目的,而让cell不复用,以牺牲内存占用为代价,无疑是饮鸩止渴,丢了西瓜,捡个芝麻.

值得的注意的是,如果在cell中实现,每个cell都添加一个定时器,这也是一笔可观的开销.

2. 在tableview的parentview中实现

既然在cell中实现遇到的坑比较多,那么又想着在外面做.这样有一个明显的好处,就是只需要一个定时器.每次触发,让每个cell上显示的时间递减.由于tableview的显示,取决于传入的数据,只要我在传入数据之前把需要传的数据处理好,这样就不会因为cell的复用机制而带来显示错乱的问题.运行代码,发现问题圆满解决!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**定时器触发*/
- (void)timechange {
 nsmutablearray *temparrm = [nsmutablearray array];
 for (nsdictionary *dict in self.dataarr) {
  nsstring *totaltime = dict[@"totaltime"];
  if ([totaltime isequaltostring:@"0"]) {
    totaltime = @"0";
  }else {
   totaltime = [nsstring stringwithformat:@"%ld",totaltime.integervalue -1];
  }
  [temparrm addobject:@{@"totaltime":totaltime}];
 }
 self.dataarr = temparrm;
 [self.pagetableview reloaddata];
}

3. 值得注意的几个地方

当我们拖动cell时,如果发现定时器不工作,可以用如下方式解决.

?
1
2
_timer = [nstimer scheduledtimerwithtimeinterval:1.0 target:self selector:@selector(timechange) userinfo:nil repeats:yes];
  [[nsrunloop currentrunloop] addtimer:_timer formode:uitrackingrunloopmode];

关于数据的传入:

  • 直接提供产品到目前为止还剩多少时间.每个产品对应一个总的时间,用于倒计时.那么,后台给我提供时间时就可以把每个产品对应的总时间返给我们.但是,这样就要求后台自己实时去计算每个产品在我们请求数据时还剩多少时间.
  • 后台把每种产品的截止时间和当前的系统时间返给我们.系统时间,我们可用于矫正自己的系统时间(app显示的时间是可以人为修改的,并且不通设备之间,ios与android之间的时间有可能存在差异,为了统一所以需要矫正),通过矫正好的时间和截止时间,我们就能知道,该产品还剩多少时间.

虽然,我这边自己用的第一种方式写的demo,但是,相比之下,我更加倾向于第二种数据的传递方式,准确性高,也能为后端同事剩些事.

总结

由于这只是一个最初的demo,也只是一些个人的初步看法,难免有些疏漏,如有纰漏,还望指正.

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:http://www.jianshu.com/p/64e3561fcb50

延伸 · 阅读

精彩推荐
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01