iphone - 在 UITableViewCell 中动态显示秒表计时器

标签 iphone ios objective-c xcode4.5 nstimer

我想保留计时器值并在新的 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];
}

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

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

编辑

如 Spynet 的评论中所写,如果您有超过 7/8 个单元格(可以适合屏幕的单元格数量),这将不起作用,因为当您滚动时,UITableView 单元格将被重复使用。因此单个单元格将用于不同的 indexPaths,因此在第一个单元格上启动计时器,然后滚动,将使您看到计时器已经每 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 中动态显示秒表计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17147224/

相关文章:

iphone - 为什么我们需要将Apple的In App Payment收据存储到服务器?

iphone - 在 iPhone 中通过快捷键启动应用程序

ios - 如何使用可选 func textViewDidEndEditing(textView : UITextView) to change text as it's entered?

ios - 沿其中心旋转 SKShapeNode

ios - iOS 中的 ImageView

iphone - With touches - 如何在到达某个 Y 点时停止 UIIMageView 移动

ios - NSMutableDictionary removeObjectForKey 奇怪的行为

ios - 将 UIImage 转换为字节数组,并发送到 WCF wsdl .NET 远程服务器

ios - 导航栏未显示在 Xcode 6 的 Storyboard 中

iphone - 如何在应用程序首次启动时显示特定屏幕