使用NSTimer的秒表错误地包括显示中的暂停时间

Gra*_*son 3 time cocoa-touch objective-c nstimer ios

这是我的iPhone秒表代码.它按预期工作,并在单击按钮时停止并恢复.

然而,当我点击"停止"时,计时器将不会在后台停止运行,当我点击"开始"恢复它时,它将更新时间并跳到当前的位置,而不是从停止的时间恢复.

我怎么能阻止NSTimer?是什么导致这种情况发生?

@implementation FirstViewController;
@synthesize stopWatchLabel;

NSDate *startDate;
NSTimer *stopWatchTimer;
int touchCount;


-(void)showActivity {

    NSDate *currentDate = [NSDate date];
    NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
    NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"mm:ss.SS"];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
    NSString *timeString=[dateFormatter stringFromDate:timerDate];
    stopWatchLabel.text = timeString;
    [dateFormatter release];
}

- (IBAction)onStartPressed:(id)sender {

    stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1/10 target:self selector:@selector(showActivity) userInfo:nil repeats:YES];

    touchCount += 1;
    if (touchCount > 1)
    {
        [stopWatchTimer fire];
    }
    else 
    {
        startDate = [[NSDate date]retain];
        [stopWatchTimer fire];

    }
}

- (IBAction)onStopPressed:(id)sender {
    [stopWatchTimer invalidate];
    stopWatchTimer = nil;
    [self showActivity];
}

- (IBAction)reset:(id)sender; {
    touchCount = 0;
    stopWatchLabel.text = @"00:00.00";
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*ell 10

您对当前显示的计算始终使用计时器的原始开始时间,因此暂停后的显示包括计时器暂停的时间间隔.

最简单的方法是存储另一个NSTimeInterval,例如secondsAlreadyRun,当计时器暂停时,并将其添加到您恢复时计算的时间间隔.startDate 每次计时器开始计数时,您都希望更新计时器.在reset:,你也可以清除那个secondsAlreadyRun间隔.

-(void)showActivity:(NSTimer *)tim {

    NSDate *currentDate = [NSDate date];
    NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
    // Add the saved interval
    timeInterval += secondsAlreadyRun;
    NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"mm:ss.SS"];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
    NSString *timeString=[dateFormatter stringFromDate:timerDate];
    stopWatchLabel.text = timeString;
    [dateFormatter release];
}

- (IBAction)onStartPressed:(id)sender {

    stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1/10 
                                                      target:self 
                                                    selector:@selector(showActivity:) 
                                                    userInfo:nil 
                                                     repeats:YES];
    // Save the new start date every time
    startDate = [[NSDate alloc] init]; // equivalent to [[NSDate date] retain];
    [stopWatchTimer fire];
}

- (IBAction)onStopPressed:(id)sender {
    // _Increment_ secondsAlreadyRun to allow for multiple pauses and restarts
    secondsAlreadyRun += [[NSDate date] timeIntervalSinceDate:startDate];
    [stopWatchTimer invalidate];
    stopWatchTimer = nil;
    [startDate release];
    [self showActivity];
}

- (IBAction)reset:(id)sender; {
    secondsAlreadyRun = 0;
    stopWatchLabel.text = @"00:00.00";
}
Run Code Online (Sandbox Code Playgroud)

别忘了在startDate合适的地方发布!还要记住,文档化的NSTimer接口是为您提供的接受一个参数的方法,它将是计时器本身.它似乎没有它,但为什么诱惑命运?

最后,既然你使用了NSDateFormatter这么多,你可能会考虑把它变成ivar或者把它放在static存储器中showActivity:,如下所示:

static NSDateFormatter * dateFormatter = nil;
if( !dateFormatter ){
    dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"mm:ss.SS"];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
}
Run Code Online (Sandbox Code Playgroud)