First, here is some working code for a stopwatch in Xcode. I got two buttons, Start
and Stop
. Their titles change when the buttons are pressed. Now I want to add a pause functionality. I know that there are many threads about this, but (I don't know why) I was not able to get it working.
So what is the best approach to implement this function in my code?
I already tried to use a pause date and subtract it from my NSTimeInterval
but got negative values ...
Thanks so far!
So I did this:
//use timer to update the ui only, store start date (NSDate) and time interval elapsed (NSTimeInterval)
//this is called when the timer is not running, nor paused - a sort of 'first run' function
-(void)onTimerStart
{
//zero the time elapsed
time_passed = 0;
//save the starting date
start_date = [NSDate date];
//start a timer that will update the ui in the onTimer function
timer = [NSTimer timerWithTimeInterval:1.0/10.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
}
//called when the timer is running to pause it
-(void)onPause
{
//calculate the time that passed ( += not = )
time_passed += [[NSDate date] timeIntervalSinceDate: start_date];
//stop the timer
[timer invalidate];
//you can get rid of the start date now (using ARC ........)
}
//restarting the timer that was paused
-(void)onUnpause
{
//get new start date
start_date = [NSDate date];
//start the timer to update ui again
timer = [NSTimer timerWithTimeInterval:1.0/10.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
}
//use this function if you are stopping - not pausing! - the timer.
-(void)onReset
{
//stop timer
[timer invalidate];
//calculate the final time that passed
//THE NEXT LINE IS PROBABLY WRONG AND HAS TO BE time_passed = 0; THEN IT WORKS
time_passed += [[NSDate date] timeIntervalSinceDate: start_date];
//get rid of the start date now
}
//use this function to update UI - this is what gets called by the timer
-(void)onTimer
{
//when timer ticks use ([[NSDate date] timeIntervalSinceDate: start_date] + time_passed)
//to get the amount of time passed for display
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self onTimerStart];
}
WORKING CODE:
#pragma mark - Timer
- (void)timer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.S"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
timerLabel.text = timeString;
}
#pragma mark - Stopwatch
- (IBAction)onStartPressed:(UIButton *)sender
{
if ([sender.titleLabel.text isEqualToString:@"Start"] && (![timer isValid]) && ([timerLabel.text isEqualToString:@"00:00.0"]))
{
startDate = [NSDate date];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:@selector(timer)
userInfo:nil
repeats:YES];
}
}
- (IBAction)onStopPressed:(UIButton *)sender
{
if ((![timer isValid]) && ([sender.titleLabel.text isEqualToString:@"Reset"]))
{
[timer invalidate];
timer = nil;
timerLabel.text = @"00:00.0";
[sender setTitle:@"Stop" forState:UIControlStateNormal];
}
if (([timer isValid]) && ([sender.titleLabel.text isEqualToString:@"Stop"]))
{
[timer invalidate];
timer = nil;
[sender setTitle:@"Reset" forState:UIControlStateNormal];
}
}