Высота изображения UITableViewCell при загрузке изображения
Я использую категорию UIImageView+AFNetworking
для загрузки асинхронного изображения. Все работает отлично, но я пробовал пару вещей и не был успешным при изменении размера ячейки в соответствии с загруженным изображением. Я хочу, чтобы изображение соответствовало ширине ячейки, но изменялось по высоте, но я не знаю, как это сделать. Я попытался перезагрузить строку, где было загружено изображение, но это просто заставляет cellForRowAtIndexPath
снова запускать и снова устанавливать все и т.д. Почти рекурсия.
Я вычисляю разницу в размере нового размера и сохраняю его в NSMutableArray
, а затем перезагружая строку в блоке успеха в UIImageView setImageWithURLRequest:placeholderImage:success:
.
Я получаю правильную высоту для нескольких строк в heightForRowAtIndexPath
, но тогда таблица начинает действовать странно, и все накладывается и т.д.
Любые идеи?
Спасибо!
ИЗМЕНИТЬ
В конце концов я использовал ответ Эзеки. Я также написал сообщение по этой теме и сделал пример приложения, которое использует эту технику.
Посмотрите на здесь.
Ответы
Ответ 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];
}