当tableView滚动时,tableViewCells中的运行计时器被覆盖

我已经试过多次询问这个问题,但是我一直没能解释发生了什么事情。 也许一些屏幕截图可能有帮助。 我只能发布一个,因为我没有足够的声望点。

在tableview滚动后截图

您可以看到其中一个定时器(2)已被重置。 我试图解决这个多种方式没有成功。 下面是将定时器放入tableview单元的代码:

-(void) calculateTimer:(NSTimer *)theTimer { self.timerItem = [theTimer userInfo]; // for date only cell if(self.timerItem.timerType == 0){ [theTimer invalidate]; } for (NRCItemCell *cell in [self.tableView visibleCells]) { NSIndexPath *ip = [self.tableView indexPathForCell:cell]; NSUInteger row = [[[NRCItemStore sharedStore]allItems] indexOfObjectIdenticalTo:self.timerItem]; if (row == ip.row){ [self configureTimers:cell forRowAtIndexPath:ip]; cell.timer.text = self.timerItem.timerOutput; cell.timerName.text = self.timerItem.timerName; } } } -(void)configureTimers:(NRCItemCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { NRCtimerItem *item = [[NRCItemStore sharedStore]allItems][indexPath.row]; NSInteger timerType = item.timerType; // timerType set by TimerTypeTableView Controller as follows: // 0 - date // 1 - seconds elapsed // 2 - minutes elapsed // 3 - hours elapsed // 4 - days elapsed // 5 - months elapsed // 6 - years elapsed switch (timerType) { case 0:{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; NSDate *date = [NSDate date]; NSString *formattedDateString = [dateFormatter stringFromDate:date]; item.timerOutput = formattedDateString; } break; case 1: { NSTimeInterval interval = [self.timerItem.startTime timeIntervalSinceNow]; interval = (-1 * interval); int time = round(interval); div_t h = div(time, 3600); //seconds total, divided by 3600 equals int hours = h.quot; // hours, divided by 60 equals div_t m = div(h.rem, 60); // minutes int minutes = m.quot; int seconds = m.rem; // and remainder is seconds // NSLog(@"%d:%d:%d", hours, minutes, seconds); //NSString *intervalString = [NSString stringWithFormat:@"%ld", (long)time]; NSString *intervalString = [NSString stringWithFormat:@"%d hours, %d minutes, %d seconds", hours, minutes, seconds]; NSString *outputString = [intervalString stringByAppendingString:@" ago"]; item.timerOutput = outputString; } break; case 2: { NSTimeInterval interval = [self.timerItem.startTime timeIntervalSinceNow]; interval = (-1 * interval); int time = roundf(interval); div_t h = div(time, 3600); // seconds total, divided by 3600 equals int hours = h.quot; // hours, divided by 60 equals div_t m = div(h.rem, 60); // minutes int minutes = m.quot; NSString *intervalString = [NSString stringWithFormat:@"%d hours, %d minutes", hours, minutes]; NSString *outputString = [intervalString stringByAppendingString:@" ago"]; item.timerOutput = outputString; } break; case 3: { NSTimeInterval interval = [self.timerItem.startTime timeIntervalSinceNow]; interval = (-1 * interval); int time = roundf(interval); div_t h = div(time, 3600); // seconds total, divided by 3600 equals int hours = h.quot; // hours NSString *intervalString = [NSString stringWithFormat:@"%d hours", hours]; NSString *outputString = [intervalString stringByAppendingString:@" ago"]; item.timerOutput = outputString; } break; case 4: { NSTimeInterval interval = [self.timerItem.startTime timeIntervalSinceNow]; interval = (-1 * interval); int time = roundf(interval); div_t h = div(time, 3600); // seconds total, divided by 3600 equals int hours = h.quot; // hours, divided by 24 equals div_t d =div(h.rem, 24); // days int days = d.quot; NSString *intervalString = [NSString stringWithFormat:@"%d days, %d hours", days, hours]; NSString *outputString = [intervalString stringByAppendingString:@" ago"]; item.timerOutput = outputString; } break; case 5: { NSTimeInterval interval = [self.timerItem.startTime timeIntervalSinceNow]; interval = (-1 * interval); int time = roundf(interval); div_t h = div(time, 3600); // seconds total, divided by 3600 equals __unused int hours = h.quot; // hours, divided by 24 equals div_t d =div(h.rem, 24); // days int days = d.quot; div_t y = div(d.rem, 12);// divided by 12 equals months int months = y.quot; NSString *intervalString = [NSString stringWithFormat:@"%d months, %d days", months, days]; NSString *outputString = [intervalString stringByAppendingString:@" ago"]; item.timerOutput = outputString; } break; case 6: { NSTimeInterval interval = [self.timerItem.startTime timeIntervalSinceNow]; interval = (-1 * interval); int time = roundf(interval); div_t h = div(time, 3600); // seconds total, divided by 3600 equals __unused int hours = h.quot; // hours, divided by 24 equals div_t d =div(h.rem, 24); // days int days = d.quot; div_t y = div(d.rem, 365);// divided by 365 equals years int years = y.quot; NSString *intervalString = [NSString stringWithFormat:@"%d years, %d days", years, days]; NSString *outputString = [intervalString stringByAppendingString:@" ago"]; item.timerOutput = outputString; } break; } } 

关键是for(NRCItemCell * cell [self.tableView visibleCells])快速枚举。 我们的想法是循环遍历可见单元格,只有在单元格的indexPath等于我的数据存储区中定时器的位置时才更新单元格。 但是,看起来像滚动tableView会导致数据存储区中indexPath和定时器的位置不匹配,从而导致错误的单元格被覆盖。 我已经search了所有的答案,并尝试了几种不同的方法,但解决scheme取决于我的自定义单元格中的字幕标签不被覆盖,除非单元格的位置匹配数据存储位置(这是MVC的工作方式,据我了解)。 但使用可重复使用的单元格和滚动显然不符合我的想法。 如果有解决scheme,我当然想要帮助。 提前致谢!

你的主要问题是重复使用单元格。 每次滚动表格时,单元格都会与其他单元格的数据重复使用。 为了保持简短,请将您的定时器数据存储在数组中,而不是存储在实际的单元格中。

Importent指针:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... cell.timerView.data = nil; //reset the data in the current timer myCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath]; if (updateCell)// Makes sure the cell is still visible updateCell.timerView.data = timersArray[indexpath.row]; }); } 

我的错。 我发现我的代码中的错误。 这根本不是tableView。 我正确地将定时器存储在一个数组中,而不是在单元格中,尽pipe这是代码中的注释所说的。 这个错误是我无意间在每次通过tableView的时候发射一个计时器,所以这些计时器会在不可预知的时间触发,然后我的代码会覆盖相应计时器的单元格。 很多debugging工作,但很好的经验。 代码正在工作。

感谢您的意见!