I am building one application which has stop watch as its accessory function. I am trying to do something very similar to iOS stop watch. I got stop, reset functionality working but I could not get start (once it stop and user click on start) and lap functions working properly. I tried to look around for this problem but I could not find anything besides one time start and reset stop watch tutorials.Here is what I have right now. Can anyone help me out here with this functions ?
// Stop Watch Code Begins
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLable.text = timeString;
[dateFormatter release];
}
-(IBAction)startTapped:(id)sender
{
if ([self.start.titleLabel.text isEqualToString:@"Start"])
{
NSLog(@"Start Tapped");
[self.start setTitle:@"Stop" forState:UIControlStateNormal];
[self.reset setTitle:@"Lap" forState:UIControlStateNormal];
self.startDate =[NSDate date];
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:@selector(updateTimer)
userInfo:nil
repeats:YES];
}
else if ([self.start.titleLabel.text isEqualToString:@"Stop"])
{
NSLog(@"Stop Tapped");
[self.start setTitle:@"Start" forState:UIControlStateNormal];
[self.reset setTitle:@"Reset" forState:UIControlStateNormal];
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[self updateTimer];
}
}
-(IBAction)resetTapped:(id)sender
{
if ([self.reset.titleLabel.text isEqualToString:@"Reset"])
{
NSLog(@"Reset Tapped");
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[stopWatchLable setText:@"00:00:00.000"];
}
else if ([self.reset.titleLabel.text isEqualToString:@"Lap"])
{
NSLog(@"Lap Tapped");
}
}
-(IBAction)hideTapped:(id)sender
{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect endFrame = self.stopWatchView.frame;
endFrame.origin.y = screenRect.origin.y + screenRect.size.height;
// start the slide down animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
// we need to perform some post operations after the animation is complete
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(slideDownDidStop)];
self.stopWatchView.frame = endFrame;
[UIView commitAnimations];
// grow the table back again in vertical size to make room for the date picker
CGRect newFrame = self.tableView.frame;
newFrame.size.height += self.stopWatchView.frame.size.height;
self.tableView.frame = newFrame;
//self.tableView.frame = screenRect;
[stopWatchTimer invalidate];
stopWatchTimer = 0;
[stopWatchLable setText:@"00:00:00.000"];
[self updateTimer];
}
Don't take this the wrong way, but you have one bad design choice in your code: You should not rely on a button text to tell you what you want to do – if at some point in the future you localize your application you'll have to redo the timer.
That said, here's how I would implement a stopwatch: You need two instance variables,
NSTimer
timer andNSDate
startDate. For a lap function you'll need another one, anNSMutableArray
laps. Your two buttons are fine, using simple logic you can decide what you have to do when tapping (untested code!):Start/Stop button
Reset/Lap button
Now you only have to modify updateTimer to do what you want it to do. In updateTimer, you should also check whether startDate is nil or not before you calculate anything. For the laps you can just loop over the laps array and calculate the difference between startDate and the date in the array, or even between the dates in the array.
I hope this helps!