4

我想保持计时器值并从新开始显示它UITableViewCell但我的问题是我能够成功地在第一个单元格上显示秒表计时器但是当我尝试添加一个新单元格时UITableView我的计时器设置为第二个单元格我无法定义如何让我的第一个计时器保持活力。

我想管理一个数组,但我想每次都调用 reload TableData,但我认为这很糟糕:(

我尝试了如下解决方法,但我没有弄清楚如何在前一个单元格上显示 timerValue,从相同计数开始工作秒表动态,从开始时开始新单元格 timerValue。

一个静态解决方案,但我的行动态插入并从 TableView 中删除,因此静态解决方案限制了我的特定行数,并寻找动态解决方案。

    - (void) putDelayOnTimeOut {


            if (!_timerQueue) {
                _timerQueue = dispatch_queue_create("timer_queue", NULL);
            }
            dispatch_async(_timerQueue, ^{

                self.startTime = [NSDate date];

                if (globalRowIndex == 0) {

                    _timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(showTimeoutActivity:) userInfo:nil repeats:YES];
                } else if (globalRowIndex == 1) {
                    _timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(showTimeoutActivity1:) userInfo:nil repeats:YES];
                }

                //[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
                [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

                //[[NSRunLoop currentRunLoop] run];
                [_timer fire];
            });

    }


    - (void)showTimeoutActivity:(id)unused
    {
        if( [_timer isValid] )
        {
            NSTimeInterval interval = [self.startTime timeIntervalSinceNow];
            interval = (-1 * interval);

            NSString *timerString = [self formatInterval:interval];
            NSLog(@"%@", timerString);

            MyCell *cell = (MyCell *)[self.activeCallTbl viewWithTag:globalRowIndex+10];
            //NSIndexPath *indexPath = [self.activeCallTbl indexPathForCell:cell];
            //NSLog(@"%d",indexPath.row);
            cell.timerLbl.text = timerString;

        }
    }


 - (void)showTimeoutActivity1:(id)unused
    {
        if( [_timer isValid] )
        {
            NSTimeInterval interval = [self.startTime timeIntervalSinceNow];
            interval = (-1 * interval);


            NSString *timerString = [self formatInterval:interval];
            NSLog(@"%@", timerString);

            MyCell *cell = (MyCell *)[self.activeCallTbl viewWithTag:globalRowIndex+10];
            //NSIndexPath *indexPath = [self.activeCallTbl indexPathForCell:cell];
            //NSLog(@"%d",indexPath.row);
            cell.timerLbl.text = timerString;

        }
    }
4

1 回答 1

14

我不确定是否完全理解您的要求……但我尝试了。

一种简单的解决方案是继承您的 UITableViewCell 并将计时器添加到单元格本身。因此单元格将具有对计时器的引用,并且每次将新单元格添加到 TableView 时都会创建一个新单元格

我附上示例代码:链接(我静态添加了3个单元格,但您可以根据需要添加,只需点击一个单元格即可启动计时器,如果再次点击计时器将从0重新开始)

创建您的自定义单元子类并添加一些方法,如下所示:

- (void) startTimer
{

    // invalidate a previous timer in case of reuse
    if (self.timer)
        [self.timer invalidate];


    self.startTime = [NSDate date];

    // create a new timer
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(calculateTimer) userInfo:nil repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

    [self.timer fire];
}

- (void)calculateTimer
{
    NSTimeInterval interval = [self.startTime timeIntervalSinceNow];
    interval = (-1 * interval);

    NSString *intervalString = [NSString stringWithFormat:@"%f", interval];

    self.timerLabel.text = intervalString;
}

然后,在 UITableViewController 实现中,只需调用

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    TimerCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    [cell startTimer];
}

有关更多详细信息,请询问或查看附件项目。

这是我找到的最快的方法,尽管有人更愿意将计时器代码和引用留在 Table View Controller 中(但您需要更多代码)

编辑

正如 Spynet 在评论中所写,如果您有超过 7/8 个单元格(可以适合屏幕的单元格数量),这将不起作用,因为当您滚动 UITableView 单元格时会重复使用。因此单个单元格将在不同的 indexPaths 中使用,因此在第一个单元格上启动计时器,然后滚动,将导致您看到计时器已经每 7/8 个单元格启动(因为它是先前创建的单元格的计时器)

要解决这个问题有很多方法。一种方法是从单元格中删除计时器并在 ViewController 中创建一个计时器数组。每个索引路径一个计时器。另一种方法(但如果单元格很多,我不推荐它)是不要重复使用单元格。

从我的示例项目开始:
1 -创建一个 nib 文件(称为 TimerCell.xib)并从情节提要复制/粘贴其中的单元格原型
2 -将此属性添加到TimerViewController

@interface TimerViewController ()
@property (strong, nonatomic) NSMutableArray *cells;
@end

3 -initWithCoder方法中初始化数组:

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        _cells = [NSMutableArray array];
    }
    return self;
}

4 -更新cellForRowAtIndexPath方法并像这样改变它:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    TimerCell *cell = nil;

    if ([self.cells count] > indexPath.row)
    {
        cell = [self.cells objectAtIndex:indexPath.row];
    } else {
        cell = [[[NSBundle mainBundle] loadNibNamed:@"TimerCell" owner:self options:nil] objectAtIndex:0];
        [self.cells addObject:cell];
    }

    // Configure the cell...

    return cell;
}

这样细胞就不会被重复使用

于 2013-06-19T14:44:51.883 回答