Анимация в представлении OpenGL ES зависает при перетаскивании UIScrollView на iPhone - PullRequest
22 голосов
/ 02 февраля 2011

У меня есть анимированное прозрачное подпредставление OpenGL ES (модификация шаблона Apple класса EAGLView), которое рисует вращающуюся сферу. Как и в случае с Apple, CADisplayLink используется на устройствах, где они доступны.

На том же экране есть UIScrollView, содержащий кнопки UIB, которые можно выбрать. Когда пользователь прокручивает UIScrollView, анимация моего EAGLView останавливается. Это поведение воспроизводится на iOS Simulator 4.2 и на iPhone OS 3.1.3 на устройстве iPhone 2G.

Есть идеи о том, что нужно сделать, чтобы предотвратить паузу EAGLView, кроме кодирования моего собственного вида прокрутки?

1 Ответ

56 голосов
/ 02 февраля 2011

Будет ли CADisplayLink срабатывать во время прокрутки, зависит от режима, с которым вы добавляете его в цикл выполнения. Вероятно, у вас есть это где-то:

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

UIApplication добавляет режим цикла выполнения, UITrackingRunLoopMode, для «отслеживания в элементах управления», который включает в себя прокрутку просмотра прокрутки. Таким образом, в этот момент runloop выключается из режима по умолчанию, и, следовательно, ваша ссылка на дисплей (а также любые таймеры, NSURLConnections и т. Д., Добавленные в режиме по умолчанию) не будет срабатывать, пока не будет восстановлен режим по умолчанию.

Быстрое исправление: измените код на:

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

UITrackingRunLoopMode считается одним из распространенных режимов.

Трата слишком большого количества времени на прерывание UIKit может привести к очень плохой реакции на управление, поэтому вам следует быть осторожным. Было бы массово расходиться с темой, но, хотя OpenGL является модальным и, следовательно, не особенно дружественным к многопоточности, вы можете использовать EAGLSharegroup для рендеринга в отдельном потоке, а затем перенести его в основной поток.


Пример из (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
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...