I have a view backed by a CAEAGLLayer, which is inside a UIScrollView. When I begin scrolling, the CADisplayLink that calls the -draw method of openGL view stops getting called.
I verified that my runloop start / stop methods don't get called when scrolling. The -draw method simply doesn't get called as soon as scrolling begins, and resumes getting called as soon as scrolling ends.
Does UIKit stop a CADisplayLink from firing as soon as scrolling starts?
The display link is added to the run loop like this:
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Maybe there is a conflict with this run loop mode and UIScrollView? Are there other run loop modes or alternative solutions to keep a CADisplayLink firing even when a UIScrollView is scrolling?
I thought there can be more than just one CADisplayLink in any application. Is that wrong?
You're not in
NSDefaultRunLoopMode
while scrolling aUIScrollView
; you're inUITrackingRunLoopMode
. So any timer scheduled only for the former won't fire in the latter. You can add yourCADisplayLink
to multiple run loop modes by callingaddToRunLoop:forMode:
repeatedly, or call it once withNSRunLoopCommonModes
, which covers both modes.They talked about this in detail, and other issues with integrating scroll views with GL, at WWDC 2012 in Session 223: "Enhancing User Experience with Scroll Views"; I recommend watching the video, as there's lots of other stuff in there that's likely relevant to your situation.
An example in (2016) Swift3...