This is my code for an iPhone stopwatch. It works as expected and stops and resumes when the buttons are clicked.
When I hit "Stop", however, the timer won't stop running in the background, and when I hit "Start" to resume it, it will update the time and skip to where it is currently instead of resuming from the stopped time.
How can I stop the NSTimer
? What is causing this to occur?
@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";
}
Best Answer
Your calculation of the current display always uses the original start time of the timer, so the display after pausing includes the interval that the timer was paused.
The easiest thing to do would be to store another
NSTimeInterval
, saysecondsAlreadyRun
, when the timer is paused, and add that to the time interval you calculate when you resume. You'll want to update the timer'sstartDate
every time the timer starts counting. Inreset:
, you would also clear out thatsecondsAlreadyRun
interval.Don't forget to release that
startDate
somewhere appropriate! Also keep in mind that the documentedNSTimer
interface is for the method you give it to accept one argument, which will be the timer itself. It seems to work without that, but why tempt fate?Finally, since you're using that
NSDateFormatter
so much, you might want to consider making it an ivar or put it instatic
storage inshowActivity:
, like so: