当tableView滚动

时间:2015-10-12 21:32:47

标签: ios objective-c uitableview timer

我曾多次尝试过这个问题,但我还没能解释发生了什么。也许一些屏幕截图可能有帮助。我只能张贴一个,因为我还没有足够的声望点。

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应该工作的方式,据我所知)。但是使用可重复使用的单元格和滚动显然不像我想象的那样工作。如果有解决方案,我肯定会得到帮助。提前谢谢!

2 个答案:

答案 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时都会触发一个计时器,因此这些计时器会在不可预测的时间触发,然后我的代码会覆盖相应计时器的单元格。很多调试工作,但很好的经验。代码现在正在运作。

感谢您的评论!