I have a UIScrollView
that has a series of labels which are rapidly updating numbers (every .06 seconds). While the scroll view is moving, however, the NSTimer
is paused and does not continue until after the scrolling and the elastic animation have finished.
How can I avoid this and have the NSTimer
run regardless of the state of the scroll view?
An easy way to fix this is adding your NSTimer
to the mainRunLoop
.
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
To remove a timer from all run loop modes on which it is installed, send an invalidate
message to the timer.
for swift:
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
(Swift) An alternative: You can use a GCD-based timer system like this one:
class GCDTimer {
private var _timer : dispatch_source_t?
init() {
}
private func _createTheTimer(interval : Double, queue : dispatch_queue_t, block : (() -> Void)) -> dispatch_source_t
{
let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer != nil)
{
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, Int64(interval * Double(NSEC_PER_SEC))), UInt64(interval * Double(NSEC_PER_SEC)), (1 * NSEC_PER_SEC) / 10);
dispatch_source_set_event_handler(timer, block);
dispatch_resume(timer);
}
return timer;
}
func start(interval : Double, block : (() -> Void))
{
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = _createTheTimer(interval, queue: queue, block: block)
}
func stop()
{
if (_timer != nil) {
dispatch_source_cancel(_timer!);
_timer = nil;
}
}
}