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

У меня есть UITableViewCell с UITableViewAutomaticDimension, который состоит из изображения и заголовка. После того, как я получаю данные из API, я перезагружаю tableView, но появляется только заголовок в UILabel, а не изображение, как на рисунке ниже. After reload and before scrolling

После того, как я прокручиваю tableView, изображения появляются и корректируются в соответствии с их размером. Как ниже After Scrolling

Я хочу, чтобы это произошло перед прокруткой.

То, что я уже пробовал

  1. Использование изображения-заполнителя, но оно приводит к тому, что загруженное изображение получает размер изображения-заполнителя, и после прокрутки размер ячейки обновляется правильно.
  2. Использование макета при необходимости или setNeedLayout
  3. Ожидание загрузки файла, а затем возврат ячейки после вычисления размера, но это приводит к отставанию просмотра таблицы при прокрутке

My cellForRowAt Код

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: Constants.custom.rawValue) as? CustomCell else {return UITableViewCell()}
    cell.update(model: arrImages[indexPath.row])
    return cell
}

Логика My Cell Class

Метод обновления

func update(model: ImageModel) {
    self.presentModel = model
}

Изменения пользовательского интерфейса в ячейке

    var presentModel: ImageModel? {
    didSet{
        if let url = presentModel?.imgURL {
            imgView.kf.indicatorType = .activity
            imgView.kf.setImage(with: url)
        }
        lblTitle.text = presentModel?.title
    }
}

Дополнительная информация Я использую стороннюю версию KingFisher для загрузки изображений.

1 Ответ

0 голосов
/ 16 ноября 2018

Вам следует перезагрузить табличное представление после загрузки изображения с URL.

В каждой ячейке может быть несколько ячеек с изображением.Поэтому вам следует вызывать метод перезагрузки tableView после асинхронной загрузки вашего изображения из URL.

Вы сказали, что изображения отображаются правильно при прокрутке ячеек вниз и на экранах, потому что функция tableView tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) будет вызываться, когда ячейка будет видна на экране.

Поэтому следует вызвать метод tableView.reloadData() или tableView.reloadRows(at: [imageLoadedCellIndexPath], with: .automatic), чтобы вызвать методы делегата и источника данных табличного представления.

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

imageView.kf.setImage(with: url, completionHandler: { 
    (image, error, cacheType, imageUrl) in

})

вместо imageView.kf.setImage(with: url).

Пример:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: Constants.custom.rawValue) as? CustomCell else {return UITableViewCell()}

    cell.update(model: arrImages[indexPath.row])

    let imageModel = arrImages[indexPath.row]

    if let url = imageModel?.imgURL {

//Check if image is already downloaded
        ImageCache.default.retrieveImage(forKey: url.absoluteString, options: nil) {
            image, cacheType in

//Image is already downloaded
            if let image = image {

                //cell.imgView.image = image
                imgView.kf.setImage(with: url) //try this line instead of above one

            } else { //Download
                imgView.kf.indicatorType = .activity
                cell.imgView.kf.setImage(with: url, completionHandler: {
                    (image, error, cacheType, imageUrl) in

                    if image != nil{

                        tableView.reloadRows(at: [indexPath], with: .automatic)

                        //OR

                        tableView.reloadData()
                    }
                })
            }
        }

    }

    return cell
}

и код комментария для загрузки изображения в ячейку, как показано ниже,

var presentModel: ImageModel? {
    didSet{
//            if let url = presentModel?.imgURL {
//                imgView.kf.indicatorType = .activity
//                imgView.kf.setImage(with: url)
//            }
              lblTitle.text = presentModel?.title
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...