我想保留计时器值并从头开始在新的 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;

        }
    }

最佳答案

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

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

我附上示例代码:Link(我静态添加了 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];
}

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

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

编辑

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

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

从我的示例项目开始:
1 - 创建一个 nib 文件(称为 TimerCell.xib)并从 Storyboard 中复制/粘贴其中的单元格原型(prototype)
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;
}

这样细胞就不会被重用

关于iphone - 在 UITableViewCell 中动态显示 StopWatch Timer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17147224/

10-12 05:58