How to Change the Nstimeinterval of an Nstimer After X Seconds

How to change the NSTimeInterval of an NSTimer after X seconds?

A few of things.

First, you can't change the time interval of a repeating NSTimer - you need to invalidate the first timer and schedule a new one for the new interval.

Second a >= comparison on a string won't work for what you are trying to achieve.

Finally, you have fallen into the same bad habit as many Swift programmers and initialised your timer variables needlessly only to subsequently throw those timers away. You should use either an optional or an implicitly unwrapped optional

@IBOutlet var displayTimeLabel: UILabel!
var startTime:NSDate?
var timer : NSTimer?
var timer2: NSTimer?
var time = 2.0

@IBAction func Start(sender: UIButton) {
if (self.timer2 == nil) {
self.time=2.0
self.timer2 = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "updateTime", userInfo: nil, repeats: true)
self.startTime = NSDate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(time, target: self, selector: "timer:", userInfo: nil, repeats: true)
}
}

func timer(timer: NSTimer){
//code
}
func updateTime() {
let currentTime = NSDate.timeIntervalSinceNow()
var elapsedTime = -self.startTime!.timeIntervalSinceNow()
if (elapsedTime >10.0 && self.time==2.0) {
timer.invalidate()
self.time=1.0
self.timer = NSTimer.scheduledTimerWithTimeInterval(time, target: self, selector: "timer:", userInfo: nil, repeats: true)
}

let minutes = UInt8(elapsedTime / 60.0)
elapsedTime -= (NSTimeInterval(minutes) * 60)
let seconds = UInt8(elapsedTime)
elapsedTime -= NSTimeInterval(seconds)
let fraction = UInt8(elapsedTime * 100)
displayTimeLabel.text = String(format: "%02d:%02d.%02d", minutes,seconds,fraction)
}

iOS: Get NSTimer to fire 5 seconds from now

The issue actually was further down in my code I was calling [controlTimer fire];. That was left over because I was trying to get it to work and I left that in there by mistake. Whoops, just wasted half an hour. So for you guys that may be having the same issue, all you need is to set the

[NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:@selector(controlTimerExpire) userInfo:nil repeats:NO];

and you don't need to explicitly call fire because the scheduled part of the scheduledTimerWithTimeInterval will fire the selector for you based on the time interval you set.

NSTimer/NSTimeInterval

Have you tried writing it the way it actually should have been written? The repeats argument is there exactly for this purpose. You can write a method like this:

@interface Whatever: UIViewController
{
NSTimer *timer;
int count;
int maxCount;
}

- (void)countDownFrom:(int)cnt;

@end

@implementation Whatever

- (void)countDownFrom:(int)cnt
{
maxCount = cnt;
count = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(doCount)
userInfo:nil
repeats:YES];
}

- (void)doCount
{
count++;
textField.text = [NSString stringWithFormat:@"Count: %d", count];
if (count >= maxCount)
{
[timer invalidate];
}
}

@end

Objective C : NStimer- How to stop timer after n hours

Add an instance variable to the class to store the start time of the timer:

YourClass.m:

@interface YourClass () {
NSTimeInterval _startTime;
}

@end

Record the current time when creating the timer:

self.timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:@selector(sendLocationUpdates) userInfo:nil repeats:YES];
_startTime = [NSDate timeIntervalSinceReferenceDate];

and test the current time in the sendLocationUpdates method:

#define TIMER_LIFE_IN_SECONDS 3000.0

- (void)sendLocationUpdates
{
// do thing

NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (now - _startTime > TIMER_LIFE_IN_SECONDS) {
[self.timer invalidate];
self.timer = nil;
}
}

How to switch execution based on NSTimer every 30 seconds?

Keep track of a timer instance with:

var timer: Timer!

Then update both functions to call the other after 30 seconds:

func first30Seconds() {
timer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(second30Seconds), userInfo:nil, repeats: false)
// Other code...
}
func second30Seconds() {
timer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(first30Seconds), userInfo:nil, repeats: false)
// Other code...
}

iphone NStimer start in 2 seconds

The following will do what you need:

 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 2 
target:self
selector:@selector(handleTimer:)
userInfo:nil
repeats:NO];

Then the delegate function:

-(void)handleTimer: (NSTimer *) timer 
{
//code
}

How to stop NSTimer?

If I am not mistaken at any given point in time, you are only triggering one NSTimer. All your different timers are differentiated only in time intervals. So, my suggestion would be to keep only one NSTimer and have your time interval differentiated. With different value picked you should first invalidate the timer and then restart it with new time interval. That said, your reset will then be much simplified and you do not need to save pickerSavedSelection in NSUserDefaults. This is how I would re-write this code:

class settingsVC: UIViewController {
var timer = NSTimer()

@IBAction func start(sender: AnyObject) {

// segue to another viewcontroller
performSegueWithIdentifier("timerOn", sender: self)

if picked == 1 {
self.timer.invalidate()

self.timer = NSTimer.scheduledTimerWithTimeInterval(10,
target: self,
selector: "timerDidEnd:",
userInfo: nil,
repeats: false)

print("timer1 started")
} else if picked == 2 {
self.timer.invalidate()

self.timer = NSTimer.scheduledTimerWithTimeInterval(20,
target: self,
selector: "timerDidEnd:",
userInfo: nil,
repeats: false)

print("timer2 started")

} else if // ....and so on{........ }
}

@IBAction func reset(sender: AnyObject) {
self.timer.invalidate()
}
}

PS: As a side note, I would advise your NSTimer to start & stop from main thread. Use GCD for that.

Set an NSTimer to fire once in the future

The method you want to use is:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval) seconds target:(id) target selector:(SEL) aSelector userInfo:(id) userInfo repeats:(BOOL) repeats

with repeats == NO arguments and seconds == 30. This will create the timer and schedule it. It will fire only once, in 30 seconds (and not immediately).

Changing fireDate of a repeating NSTimer

The best way I've found to coordinate two timers is to have just one timer, used as a pulse. I would do something like this:

// keep state on when the next fetch should happen
@property(strong,nonatomic) NSDate *fetchTime;

// keep state on how much animation to do per tick
@property(assign,nonatomic) NSInteger mapPointsPerFrame;

// run a single timer at the highest frame-rate you'll need
NSTimer *timer =[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];

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

// is it time to do a fetch?
NSDate *now = [NSDate date];
if ([self.fetchTime laterDate:now] == self.fetchTime) {
// call a method to start a new fetch
self.fetchTime = [NSDate dateWithTimeInterval:10 sinceDate:now];
}

// either way, do animations if they are needed
NSInteger mapPoints = self.mapPointsPerFrame;
while (self.mapPointsToAnimate.count && mapPoints) {
// call a method to add a map point
mapPoints--;
}
}

The only thing left to do is to set self.mapPointsPerFrame. Do that after each fetch. If your frame interval is 0.5s and you fetch every 10s, then the equation for that looks like this:

// just fetched N things and added N objects to self.mapPointsToAnimate
// try to animate them all by the next fetch
self.mapPointsPerFrame = (self.mapPointsToAnimate.count / 20) + 0.5; // 0.5 to round


Related Topics



Leave a reply



Submit