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

Высота изображения UITableViewCell при загрузке изображения

Я использую категорию UIImageView+AFNetworking для загрузки асинхронного изображения. Все работает отлично, но я пробовал пару вещей и не был успешным при изменении размера ячейки в соответствии с загруженным изображением. Я хочу, чтобы изображение соответствовало ширине ячейки, но изменялось по высоте, но я не знаю, как это сделать. Я попытался перезагрузить строку, где было загружено изображение, но это просто заставляет cellForRowAtIndexPath снова запускать и снова устанавливать все и т.д. Почти рекурсия.

Я вычисляю разницу в размере нового размера и сохраняю его в NSMutableArray, а затем перезагружая строку в блоке успеха в UIImageView setImageWithURLRequest:placeholderImage:success:.

Я получаю правильную высоту для нескольких строк в heightForRowAtIndexPath, но тогда таблица начинает действовать странно, и все накладывается и т.д.

Любые идеи?

Спасибо!

ИЗМЕНИТЬ

В конце концов я использовал ответ Эзеки. Я также написал сообщение по этой теме и сделал пример приложения, которое использует эту технику.

Посмотрите на здесь.

4b9b3361

Ответ 1

Вам нужно сохранить загруженное изображение в памяти или на диске, поэтому в следующий раз, когда вы попытаетесь получить изображение с этого URL-адреса, вы получите из кеша.

Итак, если вы это сделаете, вам придется сделать что-то вроде этого:

[tableView beginUpdates];

[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

[tableView endUpdates];

И вы должны вернуть новую высоту ячейки в этом методе источника данных табличного представления:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

Я рекомендовал бы вам использовать библиотеку SDWebImage вместо AFNetworking, поскольку он может кэшировать ваши изображения на memcache и диск для вас, и это очень просто использовать. Поэтому, если вы решите использовать его, ваш код загружаемых изображений будет выглядеть следующим образом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    ...

    [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
           placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                    success:^(UIImage *image, BOOL cached) {

                        // save height of an image to some cache
                        [self.heightsCache setObject:[NSNumber numberWithFloat:imHeight] 
                                              forKey:urlKey];

                        [tableView beginUpdates];
                        [tableView reloadRowsAtIndexPaths:@[indexPath]
                                         withRowAnimation:UITableViewRowAnimationFade];
                        [tableView endUpdates];
                    }
                    failure:^(NSError *error) {... failure code here ...}];

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // try to get image height from your own heights cache
    // if its is not there return default one
    CGFloat height = [[self.heightsCache objectForKey:urlKeyFromModelsArrayForThisCell] floatValue];
    ...
    return newHeight;
}

Ответ 2

Для меня это работает:

Вы проверяете, доступно ли изображение кеша или нет, если оно доступно, оно установлено на изображение, а если оно не загружено, а затем макет таблицы reset путем вызова перегруженных путей индекса.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *broadcastTableCellIdentifier = @"BlockbusterTableViewCell";

BlockbusterTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:broadcastTableCellIdentifier];

if (cell == nil) {
    cell = [[BlockbusterTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:broadcastTableCellIdentifier];
}

[self configureCell:cell atIndexPath:indexPath];
return cell;
}



-(void)configureCell:(BlockbusterTableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
    SportData *data = [self.webShared.arrSportsData objectAtIndex:self.selectedEvent];
    BroadcastData *broadcastData = [data.broadcastData objectAtIndex:indexPath.row];

NSURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:broadcastData.image]];

AFImageDownloader *downloader = [UIImageView sharedImageDownloader];
id <AFImageRequestCache> imageCache = downloader.imageCache;

UIImage *cacheimage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
    if (cell.imgBroadcast.image != cacheimage) {
        [cell.imgBroadcast setImageWithURLRequest:urlRequest placeholderImage:[UIImage imageNamed:@"placeholder_smaller"] success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {

                cell.imgBroadcast.image = image;
                [self.tableViewBroadcast beginUpdates];

                [self.tableViewBroadcast reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

                [self.tableViewBroadcast endUpdates];

        } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {

        }];

    }
    else{
        cell.imgBroadcast.image =cacheimage;
    }

    cell.lblTitle.text = broadcastData.title;
    cell.lblText.text = broadcastData.text;
    cell.lblEventDateTime.text = [self eventTime:broadcastData.eventTime];
}