Динамическое представление изображения таблицы в Swift - PullRequest
0 голосов
/ 11 мая 2018

У меня очень похожий вопрос, который был опубликован здесь ( Dynamic UIImageView Size Within UITableView ), где я пытаюсь динамически извлечь изображение из Firebase и настроить итоговый просмотр таблицы в соответствии с высотой данного изображения.фиксированная ширина по экрану в зависимости от соотношения сторон.Все статьи, которые я прочитал, говорят о том, чтобы вычислять ячейки на основе cellforRowAt, но мое фактическое изображение находится внутри TableViewCell.Может кто-нибудь помочь, пожалуйста?

Контроллер Tableview:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "FeedTableViewCell", for: indexPath) as! FeedTableViewCell

    cell.configureCell(post: postArray[indexPath.row])

    return cell
}

TableViewCell:

func configureCell(post: Post){

   self.postImage.sd_setImage(with: URL(string: post.postImageURL), 
    placeholderImage: UIImage(named: "default"))
}

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Прежде всего, вам нужно использовать 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()
    }
}
0 голосов
/ 11 мая 2018

у вас есть cell.setNeedsLayout() внутри обработчика завершения установки метода изображения, например:

cell. postImage.kf.setImage(with: URL) { _, _, _, _ in
    cell.layoutIfNeeded()
}
...