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
Getting Error Ambiguous Use of Tableview(_:Numberofrowsinsection:)
Get Progress of Uinavigationcontroller Swipe Back
Caching Images in Collectionviewcell in Swift
How to Get Multiple Buttons from a Single Tableviewcell
iOS + Swift, How to Redirect to Itunes Purchase Page
Random Image for Launch Screen
In iOS Avplayer, Addperiodictimeobserverforinterval Seems to Be Missing
Uilocalnotification: Playing a Custom Audio File Saved in Documents Directory
How to Get the Nondecoded Attributes from a Decoder Container in Swift 4
It Is Possible to Know If a String Is Encoded in Base64
Cocoa Singleton and Shared Instances
How to Insert Items at 0 Index to the Realm Container
My App Is Rejected with Exception Exc_Breakpoint (Sigtrap)
Fft Calculating Incorrectly - Swift
Today Extension with Uicollectionview Different Behaviour Compared to Single View Application
Getting Uiwebview API Deprecation Message After Adding Paypal Pod in My iOS App