Event tracking in UIScrollview blocks the main thread. I'm using the main thread to run a timer that drives some animation -- the result is that any user interaction with the scrollable view (dragging it up or down, etc) causes the animation (running on the main runloop) to freeze. Is there a way around this?
I've tried to RTFM about NSRunloop (CFRunLoopAddCommonMode et al), but it's pretty terse, leading me to believe that tinkering with event priorities / thread priorities is better avoided. Anyone have any insight?
Instead of using one of NSTimer's static constructors, create the timer object and schedule it manually for the "common" run loop modes:
Swift
let timer = Timer.init(timeInterval: 10, repeats: false) { (_) in
// ... do something useful after 10 seconds ...
}
RunLoop.main.add(timer, forMode: .commonModes)
Objective C
NSTimer *timer = [[NSTimer alloc] initWithFireDate: [NSDate dateWithTimeIntervalSinceNow: delayInSeconds] interval: 0 target:yourObject selector:yourSelector userInfo:nil repeats:NO];
[NSRunLoop.mainRunLoop addTimer: timer forMode: NSRunLoopCommonModes];
Your paramters when constructing the timer will be different since you're using a repeating timer, but the basic idea is to manually schedule the timer for NSRunLoopCommonModes.
What's happening is that when you're scrolling the run loop goes into a mode which prevents "default mode" tasks from executing. The static NSTimer functions all schedule into the default mode which is why they don't fire while you're scrolling. Manually scheduling the timer lets you specify the mode and NSRunLoopCommonModes includes the run mode used by scrolling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With