Почему 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
  }
Другие вопросы по тегам