I'm implementing a countdown with its value displayed on a UILabel, but have run into a problem. Here's the simplified code:
self.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countdown) userInfo:nil repeats:YES];
- (void)countdown {
self.countdownLabel.text = [NSString stringWithFormat:@"%i",[self.countdownLabel.text intValue]-1];
// Handle time out
if ([self.countdownLabel.text intValue] == 0) {
[self.countdownTimer invalidate];
self.countdownTimer = nil;
}
}
It works fine, but if I do other UI operations in the viewcontroller, like scroll a scrollview, the timer hangs as the scrollview scrolls and then boosts up to make up for the idle moments.
I tried dispatching the updating of the label to a background queue which of course didn't work.
dispatch_queue_t bgQ = dispatch_queue_create("bgQ", 0);
dispatch_async(bgQ, ^{
self.countdownLabel.text = [NSString stringWithFormat:@"%i",[self.countdownLabel.text intValue]-1];
});
What would be the solution here?
self.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countdown) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.countdownTimer forMode:NSRunLoopCommonModes];
Remember that in your countdown method you need an escape to invalidate your countdownTimer.
The timer will start without fire instruction when the
[[NSRunLoop mainRunLoop] addTimer:self.countdownTimer forMode:NSRunLoopCommonModes];
line is executed. ABSOLUTELY no dispatch async for UI changes.
Hope this helps.