How can I programmatically pause an NSTimer?

I'm using an NSTimer to do some rendering in an OpenGL based iPhone app. I have a modal dialog box that pops up and requests user input. While the user is providing input I'd like to "pause" i.e. something like this:

[myNSTimer pause];

I'm using this syntax because I've been doing things like:

[myNSTimer invalidate];

when I want it to stop.

How can I programmatically pause the NSTimer?


Just thought of updating minor fixes to kapesoftware's answer:

NSDate *pauseStart, *previousFireDate;

-(void) pauseTimer:(NSTimer *)timer { 

    pauseStart = [[NSDate dateWithTimeIntervalSinceNow:0] retain];

    previousFireDate = [[timer fireDate] retain];

    [timer setFireDate:[NSDate distantFuture]];
}

-(void) resumeTimer:(NSTimer *)timer {

    float pauseTime = -1*[pauseStart timeIntervalSinceNow];

    [timer setFireDate:[previousFireDate initWithTimeInterval:pauseTime sinceDate:previousFireDate]];

    [pauseStart release];

    [previousFireDate release];
}

From here:

http://discussions.apple.com/thread.jspa?threadID=1811475&tstart=75

"You can store the amount of time that has passed since the timer started... When the timer starts store the date in an NSDate variable. Then when the user switches... use the method timeIntervalSinceNow in the NSDate class to store how much time has passed... note that this will give a negative value for timeIntervalSinceNow. When the user returns use that value to set an appropriate timer.

I don't think there's a way to pause and restart a timer. I faced a similar situation. "


The way I accomplished this was by storing the NSTimer's firing date in a variable and then setting the firing date to INFINITY.

When I pause:

pauseStart = [[NSDate dateWithTimeIntervalSinceNow:0] retain];
previousFiringDate = [timer firingDate];
[timer setFiringDate:INFINITY]

When I unpause I add the amount of time that the timer was paused to the previous firing date:

float pauseTime = -1*[pauseStart timeIntervalSinceNow];
[timer setFireDate:[previousFireDate initWithTimeInterval:pauseTime sinceDate:previousFireDate]];

This made it a lot easier than worrying about invalidating and reinitializing the timer. I had a lot of timers so I just put them all in an array and did this to all of them. I subclassed the NSTimer in order to keep the previousFiringDate associated with that timer.

This was also better than using a BOOL of whether or not it was paused so actions wouldn't take place if the BOOL was set. This is because if something was about to happen before you pause, it won't happen after you unpause it because it will have just been skipped.


In my case, I had a variable 'seconds', and another 'timerIsEnabled'. When I wanted to pause the timer, just made the timerIsEnabled as false. Since the seconds variable was only incremented if timerIsEnabled was true, I fixed my problem. Hope this helps.