Почему UIScrollView приостанавливает мой CADisplayLink?
У меня есть представление, поддержанное CAEAGLLayer, который находится внутри UIScrollView. Когда я начинаю прокручивать, CADisplayLink, который вызывает метод -draw представления openGL, перестает вызываться.
Я проверил, что мои методы запуска / остановки runloop не вызываются при прокрутке. Метод -draw просто не вызывается, как только начинается прокрутка, и возобновляет вызов, как только заканчивается прокрутка.
UIKit останавливает запуск CADisplayLink, как только начинается прокрутка?
Ссылка на отображение добавляется в цикл выполнения следующим образом:
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Может быть, есть конфликт с этим режимом цикла выполнения и UIScrollView? Существуют ли другие режимы цикла выполнения или альтернативные решения для поддержания работы CADisplayLink даже во время прокрутки UIScrollView?
Я думал, что в любом приложении может быть больше, чем один CADisplayLink. Это неправильно?
1 ответ
Ты не в NSDefaultRunLoopMode
во время прокрутки UIScrollView
; ты в UITrackingRunLoopMode
, Таким образом, любой таймер, запланированный только для первого, не будет срабатывать во втором. Вы можете добавить свой CADisplayLink
в несколько режимов цикла addToRunLoop:forMode:
или позвоните один раз с NSRunLoopCommonModes
, который охватывает оба режима.
Они подробно обсудили это и другие вопросы, связанные с интеграцией представлений прокрутки с GL, на WWDC 2012 в сеансе 223: "Улучшение взаимодействия с представлениями прокрутки"; Я рекомендую посмотреть видео, так как есть много других вещей, которые, вероятно, имеют отношение к вашей ситуации.
Пример в (2016) Swift3...
let d = CADisplayLink(target: self, selector: #selector(ThisClassName.updateAlpha))
d.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)
//and then, for example...
func updateAlpha() {
let a = leader.layer.presentation()?.value(forKey: "opacity") as! CGFloat
follower.alpha = a
}