我曾多次尝试过这个问题,但我还没能解释发生了什么。也许一些屏幕截图可能有帮助。我只能张贴一个,因为我还没有足够的声望点。
screenshot after tableview scroll
您可以看到其中一个定时器(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((self.tableView visibleCells]中的NRCItemCell *单元格)快速枚举。我们的想法是遍历可见的单元格,只有当单元格的indexPath等于我的数据存储区中的计时器位置时才更新单元格。但是,看起来滚动tableView会导致indexPath与数据存储区中定时器的位置不匹配,从而导致错误的单元被覆盖。我已经搜索了所有的答案,并尝试了几种不同的方法,但解决方案取决于我的自定义单元格中的字幕标签没有被覆盖,除非单元格位置与数据存储位置匹配(这是MVC应该工作的方式,据我所知)。但是使用可重复使用的单元格和滚动显然不像我想象的那样工作。如果有解决方案,我肯定会得到帮助。提前谢谢!
答案 0 :(得分:0)
这里的主要问题是细胞的重复使用。每次滚动表格时,单元格都会与其他单元格的数据一起重复使用。为了简短起见,请将您的计时器数据存储在一个数组中,而不是存储在实际的单元格中。
重要指针:
- (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];
});
}
答案 1 :(得分:0)
我的坏。我在代码中发现了这个错误。它根本就没有tableView。我正确地将计时器存储在数组中,而不是存储在单元格中,即使这是代码中的注释所说的内容。错误是我无意中每次通过tableView时都会触发一个计时器,因此这些计时器会在不可预测的时间触发,然后我的代码会覆盖相应计时器的单元格。很多调试工作,但很好的经验。代码现在正在运作。
感谢您的评论!