В идеальном случае я обычно ожидаю, что 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;
}
Вот результат, который у меня получился:

Вы можете загрузить тестовый проект и поэкспериментировать с ним, чтобы получить лучшее понимание того, что я сделал выше.
person
ozgur
schedule
12.09.2016