时间:2021-05-02
前言
以前就有人问过这样一个问题:如果一个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]; }
乍看,好像一切都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];关于数据的传入:
虽然,我这边自己用的第一种方式写的demo,但是,相比之下,我更加倾向于第二种数据的传递方式,准确性高,也能为后端同事剩些事.
总结
由于这只是一个最初的demo,也只是一些个人的初步看法,难免有些疏漏,如有纰漏,还望指正.
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:http://www.jianshu.com/p/64e3561fcb50
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
手机上添加倒计时时钟呢,iOS14怎么设置倒计时,在哪里添加倒计时,下面就和小编一起来看看吧! 1、想要在iOS14桌面显示倒计时,需要使用第三方软件实现,例
写完js倒计时,突然想用java实现倒计时,写了三种实现方式一:设置时长的倒计时;二:设置时间戳的倒计时;三:使用java.util.Timer类实现的时间戳倒
写完js倒计时,突然想用java实现倒计时,写了三种实现方式一:设置时长的倒计时;二:设置时间戳的倒计时;三:使用java.util.Timer类实现的时间戳倒
需求:有多个组件可以开启倒计时,正常情况下默认倒计时时间终了后更新UI,另,用户可以取消指定倒计时。这里使用CountDownTimer进行倒计时,其中回调函数
本文实例讲述了jquery/js实现一个网页内同时调用多个倒计时的方法。分享给大家供大家参考,具体如下:最近需要网页添加多个倒计时.查阅网络,基本上都是千遍一律