Как обновить ячейку таблицы после загрузки асинхронного изображения и изменения размера изображения - PullRequest
0 голосов
/ 12 сентября 2018

Как мне обновить высоту ячейки после загрузки изображения с сервера методом Kingfisher setImage with completion handler? После загрузки изображения я изменяю его ограничение по высоте, используя следующее: cell.imageHeight.constant = image.size.height * cell.frame.size.width / image.size.width.

Образ загружается и устанавливается по методу cellForRow, но я пробовал и в willDisplayCell, те же проблемы. Я также проверяю cell.tag == indexPath.row в обработчике завершения метода setImage.

Я уже пробовал следующие методы, и ни один из них не работал:

  • heightForRow - это UITableViewAutomaticDimension, а estimatedHeightForRowAt - это некоторое значение (максимально возможная ячейка) и все другие комбинации этих 2
  • обновление таблицы / начало / конец
  • reloadRows в indexPath
  • cell.setNeedsLayout, layoutIfNeeded или layoutSubviews
  • dispatch main async

Любой из них сталкивается с одними и теми же проблемами: таблица переходов при прокрутке, неверная высота ячейки при первом отображении и ее обновление. Мне нужно прокрутить вверх и вниз, чтобы скрыть и показать эту ячейку, неправильная высота, рассчитанная по просмотру таблицы в некоторых ячейках. .

Если я прокручиваю вверх, все в порядке, потому что все изображения уже в кеше.

Как все это делают? Как это делает Facebook или Instagram? Как обновить высоту ячейки после ее получения из любого API?

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

То, что я на самом деле делал и как-то работал, таково:

if (self.firstLoaded[indexPath.row] == false) {
                            self.firstLoaded[indexPath.row] = true
                            DispatchQueue.main.async {
                                self.tableViewController.tableView.reloadData()
                            }
}

firstLoaded просто сообщает таблице, что эта строка уже получила изображение с URL и вычислила / сохранила правильную высоту.

Кроме того, я использовал это:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cellHeights[indexPath] = cell.frame.size.height
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
}

override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if let height = cellHeights[indexPath] {
            return height
        }
        return 1500
}

Я знаю, что вызов reloadData () не является хорошей практикой, но это решило мою проблему.Если у кого-то есть другие советы, пожалуйста, не стесняйтесь поделиться ими.

Спасибо!

0 голосов
/ 13 сентября 2018

Вы пытались добавить следующее в ваш viewDidLoad:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140

, тогда, где бы вы ни заполняли другие элементы, вам, конечно, нужно будет настроить ограничения и высоту для них.

Я бы порекомендовал разделить ячейку на подклассы и создать метод set для ячейки, в которую заполняются данные.таким образом, вы можете настроить ограничения для элементов в ячейке, чтобы лучше работать с данными, заполняющими ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...