19

I have the following code:

timer = [[NSTimer scheduledTimerWithTimeInterval:0.50 target:self selector:@selector(onTimer) userInfo:nil repeats:YES] retain];    

-(void) onTimer 
{
}

After every 0.50 seconds the OnTimer method is called.

But now I want to increment the time-interval.

That means:

OnTimer calls after 0.55
OnTimer calls after 0.60
OnTimer calls after 0.65
OnTimer calls after 0.70
OnTimer calls after 0.75
& so on.

Is there any solution for this?? I have tried lot but its not working.

Jorge Leitao
  • 19,085
  • 19
  • 85
  • 121
Hardik Patel
  • 937
  • 3
  • 14
  • 39

5 Answers5

21

Sure you can do this. Change repeats:YES to repeats:NO so that the timer doesn't repeat, and then in onTimer, just start a new timer with a longer interval. You need a variable to hold your interval so that you can make it a bit longer each time through onTimer. Also, you probably don't need to retain the timer anymore, as it will only fire once, and when it does, you'll get a new timer.

I'm no Objective-C expert (or iOS expert...) and it's been a while but I think something like this:

float gap = 0.50;

[NSTimer scheduledTimerWithTimeInterval:gap target:self selector:@selector(onTimer) userInfo:nil repeats:NO];

-(void) onTimer {
    gap = gap + .05;
    [NSTimer scheduledTimerWithTimeInterval:gap target:self selector:@selector(onTimer) userInfo:nil repeats:NO];
}

Something like that? Oh, and I'm really not too sure about the retain semantics here... read the docs to make sure you don't leak!

heavi5ide
  • 1,599
  • 10
  • 11
6

Here is one solution to Hardik's question using NSTimer's fireDate property (written in Swift):

Swift 2

var timeInterval = 0.50
NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: Selector("onTimer:"), userInfo: nil, repeats: true)

func onTimer(timer: NSTimer) {
    timeInterval += 0.05
    timer.fireDate = timer.fireDate.dateByAddingTimeInterval(timeInterval)
}

Swift 3, 4, 5

var timeInterval = 0.50
Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(self.onTimer), userInfo: nil, repeats: true)

@objc func onTimer(timer: Timer) {
    timeInterval += 0.05
    timer.fireDate = timer.fireDate.addingTimeInterval(timeInterval)
}
Karen Hovhannisyan
  • 1,140
  • 2
  • 21
  • 31
Daniel Witurna
  • 750
  • 6
  • 13
  • you cannot _re-fire_ a timer like this. – holex Jul 16 '14 at 09:25
  • for me it works. Here is the code: https://gist.github.com/anonymous/86005ed7049e985a34f6 And btw. the timer has repeat on true and I am just setting the next fire date. – Daniel Witurna Jul 16 '14 at 09:28
  • 1
    As far as I read the documentation for NSTimer using setFireDate is absolutely fine (https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSTimer_Class/Reference/NSTimer.html#//apple_ref/occ/instm/NSTimer/setFireDate:). – Daniel Witurna Jul 16 '14 at 11:28
  • Had a go at it, @user1415206 's code works like a charm. One thing though: I'd use `selector: Selector("onTimer:")` instead of the plain string `selector: "onTimer:"` –  Jul 17 '14 at 13:08
4

You could try adjusting the timer's FireDate, see setFireDate

CodeWombat
  • 778
  • 2
  • 7
  • 26
1

You can't change the interval at which a timer fires. No way. There's no API for doing this.

Two obvious workarounds: If you always change the interval, then you can just change the next time that the timer fires; this has precedence over the timer interval. Of course you have to do that every time the timer fires. If you sometimes change the interval, just invalidate the first timer and create a new timer with the new interval.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
0

This just work like charm for me.

- (void)FlexibleTimer {
    if (!keyTimer) {
        keyTimer = [NSTimer scheduledTimerWithTimeInterval:self.intervalOfIdleTimer
                                                      target:self
                                                    selector:@selector(keyTimerExceeded)
                                                    userInfo:nil
                                                     repeats:YES];
    }
    else {
        if (fabs([keyTimer.fireDate timeIntervalSinceNow]) < self.intervalOfIdleTimer - 1.0) {
            [keyTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:self.intervalOfIdleTimer]];
        }
    }
}

- (void)keyTimerExceeded {
    [self setNextDelayForFlexibleTimer];
    [self FlexibleTimer];
    NSLog(@"Timer Exceeded %f", [[NSDate date] timeIntervalSince1970]);
}
PrafulD
  • 548
  • 5
  • 13