ios - Using timer in a tableview re creates the timer after any scroll or table reload -
i'm using https://github.com/mineschan/mztimerlabel/ , in tableview cellforrowatindex using timer below:
uilabel *lbltimer=(uilabel *)[cell viewwithtag:10]; mztimerlabel *upgradetimer = [[mztimerlabel alloc] initwithlabel:lbltimer andtimertype:mztimerlabeltypetimer]; [upgradetimer setcountdowntime:timestamp]; [upgradetimer startwithendingblock:^(nstimeinterval timestamp) { lbltimer.text = @"✔"; }];
but after table reloading or scrolling, timer behaves strange , seems re-generates multiple timers counting in same place. how should fix while using timer?
appreciate help,
elias
i had @ mztimerlabel
, , violates mvc badly. puts belongs model (the timer count's down time) view. problem comes from. views should able recreated without having side effects on model.
i recommend ditch class, , create own. it's quite easy achieve this.
- create new class saves title , enddate
- store instances of class in model backs table
- create one nstimer refreshes tableview
- set cells.
that's code need basic countdown in table. because not store data in view can scroll as like:
@interface timer : nsobject @property (strong, nonatomic) nsdate *enddate; @property (strong, nonatomic) nsstring *title; @end @implementation timer @end @interface masterviewcontroller () { nsarray *_objects; nstimer *_refreshtimer; } @end @implementation masterviewcontroller - (void)viewdidload { [super viewdidload]; nsmutablearray *modelstore = [nsmutablearray arraywithcapacity:30]; (nsinteger = 0; < 30; i++) { timer *timer = [[timer alloc] init]; timer.enddate = [nsdate datewithtimeintervalsincenow:i*30]; timer.title = [nsstring stringwithformat:@"timer %ld seconds", (long)i*30]; [modelstore addobject:timer]; } _objects = modelstore; } - (void)viewwillappear:(bool)animated { [super viewwillappear:animated]; [_refreshtimer invalidate]; // timer should not exist, in case. _refreshtimer = [nstimer timerwithtimeinterval:0.5f target:self selector:@selector(refreshview:) userinfo:nil repeats:yes]; // should fire while scrolling, need add timer manually: [[nsrunloop currentrunloop] addtimer:_refreshtimer formode:nsrunloopcommonmodes]; } - (void)viewdiddisappear:(bool)animated { [super viewdiddisappear:animated]; [_refreshtimer invalidate]; _refreshtimer = nil; } - (void)refreshview:(nstimer *)timer { // refresh visible cells (uitableviewcell *cell in [self.tableview visiblecells]) { nsindexpath *indexpath = [self.tableview indexpathforcell:cell]; [self configurecell:cell forrowatindexpath:indexpath]; } } #pragma mark - table view - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { return _objects.count; } - (void)configurecell:(uitableviewcell *)cell forrowatindexpath:(nsindexpath *)indexpath { timer *timer = _objects[indexpath.row]; cell.textlabel.text = timer.title; nsinteger timeuntilend = (nsinteger)[timer.enddate timeintervalsincedate:[nsdate date]]; if (timeuntilend <= 0) { cell.detailtextlabel.text = @"finished"; } else { nsinteger seconds = timeuntilend % 60; nsinteger minutes = (timeuntilend / 60) % 60; nsinteger hours = (timeuntilend / 3600); cell.detailtextlabel.text = [nsstring stringwithformat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds]; } } - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:@"cell" forindexpath:indexpath]; [self configurecell:cell forrowatindexpath:indexpath]; return cell; } @end
Comments
Post a Comment