CADisplayLink перестает обновляться при прокрутке UIScrollView
Заголовок не требует пояснений, но у меня есть анимация в цикле, запускаемом CADisplayLink. Однако, как только я прокручиваю UIScrollView, который я добавил в мою иерархию представлений, анимация немедленно останавливается, а затем снова возвращается, когда прокрутка полностью остановилась и остановилась....
В любом случае, чтобы отменить это поведение?
8 ответов
Запустите ссылку отображения (используя -addToRunLoop:forMode:
) в другом потоке с другим циклом выполнения. Поэтому создайте новый поток, создайте цикл выполнения в этом потоке и запустите CADisplayLink в этом потоке / цикле выполнения.
Вы также можете смягчить последствия этой проблемы с помощью NSRunLoopCommonModes
вместо NSDefaultRunLoopModes
:
[displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
Использование UITrackingRunLoopMode
, Он специально разработан для прокрутки материалов.
В противном случае просто вызовите render & present рутину в -scrollViewDidScroll
,
Здесь вы можете найти лучшее (и более сложное) решение:
Анимация в представлении OpenGL ES зависает при перетаскивании UIScrollView на iPhone
это позволяет вам использовать 'NSRunLoopCommonModes' и избегает зависания OpenGL при удерживании пальца без прокрутки.
Это связано с тем, что обнаружил Дуг (установив интервал кадров CADisplayLink равным 2 вместо 1, фиксирующего UIScrollView).
На самом деле CADisplayLink поддерживает несколько RunloopMode. попробуй это:
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:UITrackingRunLoopMode];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
NSRunLoopCommonModes, кажется, портит бодрость и непрерывность uiscrollview.
Я обнаружил, что если я установлю интервал кадров в 2 вместо 1 (так 30 кадров в секунду), все работает нормально. Так что я делаю, устанавливая его на 2, когда появляется мой поповер, и сбрасывая его на 1, когда он закрывается.
Мы исправили эту же проблему, изменив frameInterval
от 1 до 2. Это, по сути, вдвое уменьшает скорость рендеринга вашей сцены OpenGL, но все равно может отображаться достаточно для ваших нужд.
frameInterval Количество кадров, которое должно пройти, прежде чем ссылка на отображение снова уведомит цель.
@property (nonatomic) NSInteger frameInterval Обсуждение Значение по умолчанию равно 1, что приводит к уведомлению вашего приложения о частоте обновления экрана. Если задано значение больше 1, ссылка на отображение уведомляет ваше приложение с частотой собственной частоты обновления. Например, установка интервала в 2 заставляет ссылку на дисплей запускать каждый второй кадр, обеспечивая половину частоты кадров.
Установка этого значения меньше 1 приводит к неопределенному поведению и является ошибкой программиста.