异步下载映像后,表单元格框架未更新

时间:2018-11-15 14:37:54

标签: ios uitableview swift4

我有一个带有图像和标题的UITableViewAutomaticDimension的UITableViewCell。从API获取数据后,我重新加载tableView,但仅UILabel中的标题出现,而不是图像,如下图所示 After reload and before scrolling

在我滚动tableView之后,图像会出现并根据那里的大小进行调整。像下面 After Scrolling

我希望在滚动之前发生这种情况。

我已经尝试过的事情

  1. 使用占位符图像,但结果是下载的图像占用占位符图像大小,并且在滚动后,单元格大小已正确更新。
  2. 根据需要使用布局或setNeedLayout
  3. 等待文件下载,然后在计算大小后返回单元格,但这会导致滚动时滞后于表格视图

我的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
}

我的细胞类逻辑

更新方法

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 :(得分:0)

从url加载图像后,您应该重新加载表格视图。

您可能有多个单元格,每个单元格上都有图像。因此,一旦从url中异步下载了图片,就应该调用tableView的reload方法。

您说当向下或向下滚动屏幕上的单元格时图像会正确显示,因为当单元格即将在屏幕上可见时,将调用tableView的func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)。 / p>

因此,您应该调用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
        }
    }