В идеальном случае, я обычно ожидать, что API, чтобы вернуть все изображения с одинаковым размером или размером, который можно настроить с помощью параметров строки запроса, например: /get_image/?width=400&height=400
т.д.
Во всяком случае, проблема вот то, что вы не можете обновить высоту ячейки после ее создания и быть готовым к рисованию на экране (другими словами, как только она была возвращена с cellForRowAtIndexPath
), если вы не перезагрузите эту ячейку или всю таблицу просмотреть вручную. К счастью для нас, sd_setImageWithURL
работает в асинхронном режиме, что означает, что у вас будет возможность позвонить tableView.reloadRowsAtIndexPath
после того, как изображение будет извлечено и сохранено.
Перезагрузка вызовет heightForRowAtIndexPath
для вызова в перезаряженную ячейку, поэтому на этот раз мы получим правильную высоту.
(Поскольку ячейки табличного представления являются объектами многократного использования, они не хранят никакой информации о данных, которые они используют для настройки своего пользовательского интерфейса. Таким образом, вам необходимо сохранить изображения в контроллере просмотра, предпочтительно внутри массива ,)
@interface ViewController()
@property (nonatomic, strong) NSMutableArray *fetchedImages;
@end
@implementation ViewController
...
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *image = [self.fetchedImages objectAtIndex:indexPath.row];
if (image) {
return image.size.height + 1.0; // 1.0 for the separator.
}
else {
return 50.0; // Default value..
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.fetchedImages.count;
}
С учетом всего сказанного, можно сделать что-то вроде следующего в (tableView:cellForRowAtIndexPath:)
метода:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
UIImage *image = [self.fetchedImages objectAtIndex:indexPath.row];
if (image) {
// If there is image don't bother fetching the image.
cell.imageView.image = image;
}
else {
NSURL *imageURL = [self.imageURLs objectAtIndex:indexPath.row];
[cell.imageView sd_setImageWithURL:imageURL placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (image) {
[self.fetchedImages replaceObjectAtIndex:indexPath.row withObject:image];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}];
return cell;
}
Вот результат я в конечном итоге:
You можно загрузить test project и поиграть с ним, чтобы лучше понять, что я сделал Бова.
Проверить это [категория] (https://github.com/foundry/UIImageMetadata) – iphonic
может у обеспечить способ, как использовать это в моем случае – Simmy
Категория может получать метаданные изображения, например EXIF, который содержит информацию о разрешении изображения, поэтому вы можете получить размер изображения перед загрузкой изображения и предоставить размер ячейки. – iphonic