Подтвердить что ты не робот

Отложенный рендеринг UIImageView в UITableView

Хорошо, у меня есть UITableView с пользовательским UITableViewCell, каждый из которых содержит UIImageView, изображения которого загружаются асинхронно через NSURLConnection. Все довольно стандартный материал...

Проблема в том, что при прокрутке таблицы новые изображения загружаются в фоновом режиме правильно, но не RENDERED, пока таблица не перестанет двигаться.

Как мне заставить таблицу отображать ее содержимое даже при ее перемещении? Спасибо.

- ОБНОВЛЕНИЕ -

После более близкого взгляда я обнаружил, что методы делегата NSURLConnection не срабатывают, пока таблица не перестанет прокручиваться. Не знаю, почему. Любая помощь будет отличной.

4b9b3361

Ответ 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];
    }