CADisplayLink перестает обновляться при прокрутке UIScrollView

Заголовок не требует пояснений, но у меня есть анимация в цикле, запускаемом CADisplayLink. Однако, как только я прокручиваю UIScrollView, который я добавил в мою иерархию представлений, анимация немедленно останавливается, а затем снова возвращается, когда прокрутка полностью остановилась и остановилась....

В любом случае, чтобы отменить это поведение?

8 ответов

Решение

Запустите ссылку отображения (используя -addToRunLoop:forMode:) в другом потоке с другим циклом выполнения. Поэтому создайте новый поток, создайте цикл выполнения в этом потоке и запустите CADisplayLink в этом потоке / цикле выполнения.

Вы также можете смягчить последствия этой проблемы с помощью NSRunLoopCommonModes вместо NSDefaultRunLoopModes:

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

Использование UITrackingRunLoopMode, Он специально разработан для прокрутки материалов.

В противном случае просто вызовите render & present рутину в -scrollViewDidScroll,

UIScrollView не работает и останавливает прокрутку с помощью рендеринга OpenGL (связанный CADisplayLink, NSRunLoop)

Здесь вы можете найти лучшее (и более сложное) решение:

Анимация в представлении 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 приводит к неопределенному поведению и является ошибкой программиста.

Другие вопросы по тегам