Отложенный рендеринг UIImageView в UITableView
Хорошо, у меня есть UITableView
с пользовательским UITableViewCell
, каждый из которых содержит UIImageView
, изображения которого загружаются асинхронно через NSURLConnection
. Все довольно стандартный материал...
Проблема в том, что при прокрутке таблицы новые изображения загружаются в фоновом режиме правильно, но не RENDERED, пока таблица не перестанет двигаться.
Как мне заставить таблицу отображать ее содержимое даже при ее перемещении?
Спасибо.
- ОБНОВЛЕНИЕ -
После более близкого взгляда я обнаружил, что методы делегата NSURLConnection
не срабатывают, пока таблица не перестанет прокручиваться. Не знаю, почему. Любая помощь будет отличной.
Ответы
Ответ 1
Причина, по которой сообщения делегата соединения не срабатывают, пока вы не прекратите прокрутку, заключается в том, что во время прокрутки цикл выполнения находится в UITrackingRunLoopMode
. По умолчанию NSURLConnection
назначается только в NSDefaultRunLoopMode
, поэтому вы не получаете никаких сообщений при прокрутке.
Здесь, как запланировать соединение в "общих" режимах, включая UITrackingRunLoopMode
:
NSURLRequest *request = ...
NSURLConnection *connection = [[NSURLConnection alloc]
initWithRequest:request
delegate:self
startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
[connection start];
Обратите внимание, что вы должны указать startImmediately:NO
в инициализаторе, который, похоже, работает с документом Apple, который предлагает вам изменить режимы цикла выполнения даже после его запуска.
Ответ 2
Вы должны прочитать NSRunLoop. Я подозреваю, что во время прокрутки цикл выполнения работает в NSEventTrackingRunLoopMode, а NSURLConnection не включен в этот режим. Вы могли бы обойти это, позвонив в расписание NSURLConnectionInRunLoop: forMode:, так что загрузка может произойти во время прокрутки.
Это, вероятно, повлияет на производительность прокрутки, что, вероятно, является причиной отдельного режима цикла запуска. Но попробуйте и посмотрите, как он себя чувствует!
Ответ 3
Если вы закроете загрузку и обновление изображения в NSOperation, обновления будут выполняться в виде прокрутки таблицы.
Другим преимуществом NSOperation является то, что вы можете отменить операцию, когда ячейка скользит за кадром. Он будет чувствовать себя намного более восприимчивым к пользователю. Особенно если они быстро прокрутят длинный список. В этом году Tech-Talk Apple поощрял эту технику.
Если ваши списки не так долго или вы предпочитаете, чтобы они продолжали загружаться, вы можете вместо этого использовать приоритеты NSOperation.
Ответ 4
Сначала... ваше соединение, вероятно, даже не начинается, пока не дойдет до mainRunLoop и что там также обрабатывается прокручивающая анимация.
Я столкнулся с той же проблемой и исправил ее, указав соединения для изображений сразу же после создания.
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:wrapper.request delegate:wrapper];
[connection start];
В процедуре завершения, в которой вы получаете изображение, и установите cell.imageView.image на полученное изображение, вы должны проверить, принадлежит ли эта ячейка к одной из ячеек, отображаемых в настоящее время в таблице... и if поэтому вызовите [tableView reloadData].
NSInteger itemIndex = theIndexInTheRowDataOfTheCellYouStuffedTheImage
NSArray *indicies = [_tableView indexPathsForVisibleRows];
NSUInteger rows = indicies.count;
if (rows > 0 &&
itemIndex >= ((NSIndexPath *)[indicies objectAtIndex:0]).row &&
itemIndex <= ((NSIndexPath *)[indicies objectAtIndex:rows - 1]).row)
{
[_tableView reloadData];
}