Проблема в том, что вы не можете обновить высоту ячейки после того, как она была создана и нарисована на экране. Но что вы можете сделать, так это то, что когда вы загружаете изображение, вы уведомляете TableView о перезагрузке указанной строки c, к которой принадлежит изображение. Это назовет heightForRowAtIndexPath
, но теперь вы будете знать точную высоту изображения.
Определите массив, в котором вы будете хранить извлеченные изображения в вашем ViewController
.
private var images: [UIImage] = []
Теперь при создании ячейки вы либо передаете это изображение в ячейку, либо запускаете задачу загрузки с обратным вызовом, который уведомит TableView о перезагрузке указанной строки c.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourCell") as? YourCell
if images.count > indexPath.row {
// We have the image, load it
cell?.setupContentWith(image: images[indexPath.row])
} else {
// We do not have the image, download it
cell?.setupContent(url: URL(string: imageUrls[indexPath.row]), completion: { [weak self] image in
self?.images.append(image)
tableView.reloadRows(at: [indexPath], with: .none)
})
}
return cell ?? UITableViewCell()
}
Функции внутри TableViewCell могут выглядеть примерно так:
private func setupContent(url: URL?, completion: @escaping (UIImage) -> Void) {
guard let url = url else { return }
yourImageView?.downloaded(from: url, completion: completion)
}
private func setupContentWith(image: UIImage) {
yourImageView?.image = image
}
И, наконец, когда у вас нет изображения, вы можете вернуть некоторую высоту по умолчанию, которую вы считаете подходящей. И если у вас есть изображение, вы возвращаете его высоту.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if images.count > indexPath.row {
// We have the image, return it's height
return images[indexPath.row].size.height
} else {
// We do not have the image, return some default height
return 50 // Or some height you find approriate
}
}