ios - 即使计时器在视觉上已经停止,NSTimer 也会继续计数

标签 ios nsdate nstimer

我正在创建一个计时器,其格式为 HH:mm,但我现在的问题是暂停计时器并恢复它。现在,当您暂停计时器时,它会继续在后台计数,但可见部分已停止。一旦您单击“恢复”按钮,计时器就会更新到它停止的位置,根据您暂停的时间,计时器可能会超出应有的任何数字。

例如,如果计时器计数到 5,则您暂停计时器,计时器现在位于 5,一旦您单击恢复,计时器可能会从 15 开始,因为自您暂停以来已经过去了 10 秒。下面是我的代码,我从几个地方组合了这些代码以使其正常工作:

- (void) createTimerPage
{
    _dateFormat = [NSDate date];

    // Add pause button
    UIImage *pause = [UIImage imageNamed:@"pause.png"];
    _pauseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    _pauseBtn.frame = CGRectMake(151, 17, 32, 32);
    [_pauseBtn addTarget:self action:@selector(pauseTimer) forControlEvents:UIControlEventTouchUpInside];
    [_pauseBtn setBackgroundImage:pause forState:UIControlStateNormal];
}

- (void) startTimer
{
    // Start timer
    NSInteger secondsSinceStart = (NSInteger) [[NSDate date] timeIntervalSinceDate:_dateFormat];
    NSInteger seconds = secondsSinceStart % 60;
    NSInteger minutes = (secondsSinceStart / 60) % 60;
    NSString *result = nil;
    result = [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
    _timerText.text = result;
    [_timerBtns addSubview:_pauseBtn];
}

- (void) startPressed
{
   [_time invalidate];
   _time = [NSTimer scheduledTimerWithTimeInterval:1.0
                                        target:self
                                        selector:@selector(startTimer)
                                       userInfo:nil
                                        repeats:YES];
}

- (void) pauseTimer
{
    if (_time) {
        // pause timer
        [_time invalidate];
        [_timerBtns addSubview:_playBtn];
    }
}

最佳答案

我怀疑问题是您将“开始时间”存储在名为“_dateFormat”的变量中。该变量仅在调用 createTimerPage 时设置,当然,当您稍后尝试确定 startTimer 中的 secondsSinceStart 时,它仍在计算自调用 createTimerPage 以来的时间。

老实说,对于您正在尝试做的事情,我根本不会担心开始时间。相反,我只使用计时器方法被调用次数的计数器。我还会重命名您的一些方法,以使实际发生的事情更清楚。例如,您的“startTimer”方法实际上并未启动计时器。当您的一秒计时器触发时,它会被调用。

最后,另一个问题是您不断添加 subview ,但至少在发布代码时从未删除它们。每次添加新 subview 时,您都可以(应该)删除未使用的 subview 。不过,老实说,您最好将两个 View 保留为 View 层次结构的一部分,并使用隐藏属性仅显示其中一个。

像这样的东西会做你想做的事:

NSUInteger _timerSeconds;
NSTimer * _timer;

- (void) createTimerPage
{
    // Add pause button
    UIImage *pause = [UIImage imageNamed:@"pause.png"];
    _pauseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    _pauseBtn.frame = CGRectMake(151, 17, 32, 32);
    [_pauseBtn addTarget:self action:@selector(pausePressed) forControlEvents:UIControlEventTouchUpInside];
    [_pauseBtn setBackgroundImage:pause forState:UIControlStateNormal];
    [_timerBtns addSubview:_pauseBtn];
}

- (void) timerFired
{
    _timerSeconds++;
    NSInteger seconds = _timerSeconds % 60;
    NSInteger minutes = (_timerSeconds / 60) % 60;
    NSString * result = [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
    _timerText.text = result;
}

- (void) startPressed
{
    // start timer
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                             target:self
                                           selector:@selector(timerFired)
                                           userInfo:nil
                                            repeats:YES];

    _playBtn.hidden = YES;
    _pauseBtn.hidden = NO;
}

- (void) pausePressed
{
    if (_timer) {
        // pause timer
        [_timer invalidate];
        _playBtn.hidden = NO;
        _pauseBtn.hidden = YES;
    }
}

关于ios - 即使计时器在视觉上已经停止,NSTimer 也会继续计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20529480/

相关文章:

ios - 在入职流程结束时快速显示按钮

ios - 带有 BG 颜色和文本的自定义 UIBarButtonItem Swift 3

swift - NSDate 和 UIDatepicker Swift

ios - 图表 : How to set colors of left and right axis labels in LineChartView?

ios - Swift(解析)顶部 UITableViewCell 的新行?

swift - 每个月在 tableView 中添加一个新行

ios - 将 UTC 日期格式转换为本地 nsdate

swift - 如何使用特定数量的计数在 SWIFT 中循环 NSTimer

ios - 无法停止 NSTimer

ios - 当应用程序在后台时保持 NSTimer 运行