Прежде всего, вам нужно использовать Autolayout для вычисления правильной высоты ячейки путем создания правильного набора ограничений, которые будут определять высоту ячейки на основе содержимого. Я собираюсь предположить, что вы это сделали.
Затем вы должны указать tableView
, что хотите использовать Autolayout для расчета высоты:
// my best estimation of the height
tableView.estimatedRowHeight = 144
// but the real height is calculated by autolayout
tableView.rowHeight = UITableViewAutomaticDimension
Теперь это будет работать, если autolayout сможет правильно рассчитать высоту в cellForRowAt
. Но так как изображение загружается асинхронно, изображение устанавливается позже, когда ячейка может быть уже представлена. Это требует, чтобы вы указали способ, которым ячейка может сообщить tableView
, что она загрузила свой контент, и что ее макет необходимо пересчитать. Для этого используйте этот метод в viewController
с tableView
:
func recalculateTableViewLayout() {
self.tableView.beginUpdates()
self.tableView.setNeedsLayout()
self.tableView.endUpdates()
}
Вам нужно будет передать ссылку на viewController
с tableView
в каждую ячейку (для этого я рекомендую использовать шаблон делегата, здесь для краткости я просто набросаю его, используя его напрямую):
class FeedTableViewCell: UITableViewCell {
weak var feedViewController: FeedViewController?
// etc.
А в cellForRowAt
:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FeedTableViewCell", for: indexPath) as! FeedTableViewCell
cell.feedViewController = self
cell.configureCell(post: postArray[indexPath.row])
return cell
}
Затем используйте обработчик завершения sd_setImage
, чтобы tableView
пересчитать его макет при загрузке изображения:
func configureCell(post: Post){
self.postImage.sd_setImage(with: URL(string: post.postImageURL), placeholderImage: UIImage(named: "default")) { (image, error, cache, url) in
self.feedViewController?.recalculateTableViewLayout()
}
}