Мои пользовательские элементы пользовательского интерфейса не обновляются, пока прокручивается UIScrollView
У меня есть элемент UI кругового круга, который обновляется NSTimer. У меня также есть UIScrollView, который будет "блокировать" вращающийся круг во время прокрутки. Это ожидалось, потому что таймер и свиток видят, где оба в одном и том же потоке.
Поэтому я помещаю таймер в отдельный поток, который в основном отлично работает! Я вижу, что он работает, потому что NSLogs продолжают появляться даже при прокрутке.
Но моя проблема в том, что мой вращающийся круг все еще останавливается при прокрутке! Я подозреваю, что перерисовка остановлена до следующей итерации цикла запуска основного потока (?). Поэтому, даже если его угол изменяется все время, он не может быть перерисован...
Любые идеи, что я могу сделать? Спасибо!
Ответы
Ответ 1
Во время прокрутки цикл запуска основного потока находится в UITrackingRunLoopMode. Поэтому вам нужно запланировать таймер в этом режиме (возможно, в дополнение к режиму по умолчанию). Я считаю, что NSRunLoopCommonModes включает режимы отслеживания по умолчанию и отслеживания событий, поэтому вы можете просто сделать это:
NSTimer *timer = [NSTimer timerWithTimeInterval:0.42 target:foo selector:@selector(doSomething) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
Кстати, вы должны сделать все это в основном потоке. Нет необходимости создавать фоновый поток (если только каждый вызов таймера не выполняет некоторую длительную обработку).
Ответ 2
UIScrollView не только блокирует NSTimers, но и блокирует весь основной поток. И объекты UIKit должны быть доступны только в основном потоке (и, часто, ограничены непредсказуемыми способами, если вы пытаетесь уклониться от этого ограничения), что, вероятно, поэтому - даже если у вас есть часы, поступающие из внешнего потока - вы 'не удается опубликовать обновления.
Это немного уловка, но есть ли способ, которым можно добиться анимации с помощью CoreAnimation? Вещи, связанные с этим, продолжают работать независимо от того, что происходит в основной теме.
Ответ 3
Вы правы, что UIScrollView
не обновляет свой просмотр содержимого во время прокрутки.
Вероятно, ваш лучший выбор - и это что-то вроде взлома - это отображение вашего анимационного представления отдельно (возможно, в рамке-представлении, чтобы получить бесплатное обрезание) и использовать обратные вызовы делегата прокрутки для поиска текущее положение прокрутки и соответственно положение вашей анимации.
ПРИМЕЧАНИЕ: это предложение - это взлом! Это не лучшие практики, и это, безусловно, соответствует простому, поддерживаемому коду без побочных эффектов. Тем не менее, это единственный способ, который я могу представить, чтобы получить нужный дисплей.
Еще один способ: переосмыслить важность отображения анимированного содержимого прокрутки во время прокрутки.