Reverse NSTimer for scheduledTimerWithTimeInterval in Objective-C - ios

I have NSTimer and Action for it. But I want to call Action after 5s for first time, 4s for second time and ... .
_timepast = 6;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(handleDelay) userInfo:nil repeats:YES];
-(void)handleDelay
{
_timepast = _timepast - 1;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timepast * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self handleTimer];
});
}

First of all if you want to start action after 5 sec and then create first timer which trigger after 5 sec delay and then invalidate first timer and start your second timer with countDown of 5. It means after 5 sec delay you will your selector called and handle action in it. I am giving you code for how second timer works. I hope you will know how to handle first timer for 5 sec delay.
Create 2 variable
var timerCount = 5
var timer : Timer!
Create timer of 1 sec interval
timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(self.startTimer), userInfo: nil, repeats: true)
In the selector method write reverse checking like,
func startTimer() {
if timerCount > 0 {
label.text = String(timerCount--)
}
else {
timer.invalidate()
}
}

Related

How to create a timer to reload a tableView on a fixed interval?

for a school project we need to create a application which refreshes its content on a fixed interval. The content is in a collectionView. The interval is once every 40 seconds. What would be the best approach to achieve this?
Try the following :
NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:40 target:self selector:#selector(yourMethod) userInfo:nil repeats:YES];
yourMethod func
-(void)yourMethod{
[self.yourCollectionView reloadData];
}
When you don't want to timer, stop the timer using invalidate.
[aTimer invalidate];
aTimer = nil;
Hope it helps..
Use the code below
NSTimer *current_timer = [NSTimer timerWithTimeInterval:10.0 target:self selector:#selector(updateDefaultTimer:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:current_timer forMode:NSDefaultRunLoopMode];
- (void) updateDefaultTimer:(NSTimer *)timer{
[self.yourCollectionView reloadData];
}
updateDefaultTimer will call every 10 sec
You can create repeated timer and reload your collection in its function.
var timer: NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer.scheduledTimerWithTimeInterval(40.0, target: self, selector: #selector(reloadCollection), userInfo: nil, repeats: true)
}
func reloadCollection() {
// your code here
// ...
collectionView.reloadData()
}

iOS Thread Loop Logic

Im a little confused on the logic of creating a loop on a thread that is continuous . Just need a point in the Right Direction.
GCD or NSOpereation?
I have this JSON file that gets updated from a web job every 5 minutes.
Is there a way I can run a thread in the background that constantly checks the JSON for changes every N minutes or seconds ?
I', thinking i could use, just cant figure how I would implement
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC),
I would recommend using NSTimer with repeats: true:
override func viewDidLoad() {
super.viewDidLoad()
let _ = NSTimer.scheduledTimerWithTimeInterval(300, target: self, selector: Selector("checkForJSONChanges"), userInfo: nil, repeats: true)
}
func checkForJSONChanges() {
...
}
Or if you're using Objective-C:
- (void) viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:300.0f target:self selector:#selector(checkForJSONChanges) userInfo:nil repeats:YES];
}
- (void) checkForJSONChanges {
...
}

Any idea on how to "slow down time" with an NSTimer?

I created a timer, and was wondering if it is at all possible to make the timer go slower when it reaches a certain second: 1..2..3..4..4.1..4.2.
For example, the timer is increasing by 1 second, then at 4 seconds, the time slows down showing milliseconds.
if(i = 4) {
}
It depends on what you want.
Of course, you can't slow down the time, but you can simulate it.
For example, you check how much time has already passed. If it is 1, 2, 3 seconds, you NSLog 1, 2, 3. Then when 4 seconds has passed, you start logging milliseconds.
E.g.
if (i < 4) {
NSLog(#"%d", i);
} else {
NSLog(#"4.%d", i - 4);
}
Sure, logging can be substituted with whatever you need.
P.S. The answer is in Objective-C, but that changes nothing.
You can use a solution like this:
Declare a float to register your time and a NSTimer to perform the action.
#property NSTimer *timer;
#property float time;
Call startTimer to start the actions.
- (void) startTimer {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(secondsAction)
userInfo:nil
repeats:YES];
}
- (void) secondsAction {
self.time += 1;
NSLog(#"%d", (int)self.time);
if(self.time == 4) {
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:#selector(milisecondsAction)
userInfo:nil
repeats:YES];
}
}
- (void) milisecondsAction {
self.time += 0.1;
NSLog(#"%.1f", self.time);
}

How to trigger NSTimer right away?

I need to call a method when my app starts and then call the same method every 5 seconds.
My code is pretty simple:
// Call the method right away
[self updatestuff:nil]
// Set up a timer so the method is called every 5 seconds
timer = [NSTimer scheduledTimerWithTimeInterval: 5
target: self
selector: #selector(updatestuff:)
userInfo: nil
repeats: YES];
Is there an option for the timer so it's trigger right away and then every 5 seconds ?
NSTimer's -fire, [timer fire]; is what you're looking for.
That will fire/immediately call the timer dismissing the time delay.
You can't schedule the timer and fire the event immediately all in the same line of code. So you have to do it in 2 lines of code.
First, schedule the timer, then immediately call 'fire' on your timer:
timer = [NSTimer scheduledTimerWithTimeInterval: 5
target: self
selector: #selector(updatestuff:)
userInfo: nil
repeats: YES];
[timer fire];
When fire is called, the time interval that your timer waits to fire will reset because it just ran, and then will continue to run thereafter at the designated interval--in this case, every 5 seconds.
In Swift:
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(foo), userInfo: nil, repeats: true)
timer.fire()
You can initialise the timer and fire it in the same line:
[(checkStatusTimer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:#selector(checkStatusTimerTick:) userInfo:nil repeats:YES]) fire];
In swift this can be achieved in one line like:
Timer.scheduledTimer(withTimeInterval: intervalInSec, repeats: true) {
}

How do I change timing for NSTimer?

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.
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!
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)
}
You could try adjusting the timer's FireDate, see setFireDate
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.
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]);
}

Resources