ios - 带有异步 UIImageView 的自动布局 UITableViewCell 不工作

标签 ios swift uitableview autolayout

我有一个配置非常基本的 UITableView。表格 View 单元格仅包含一个 UIImageView

查看层次结构:

View Hierarchy

我想在 UIImageView 中显示不同大小的图像。 UIImageView 的宽度需要固定为可变高度。

Auto Layout 应该能够自动调整单元格的大小,但在异步下载图像时它不起作用。

这是我的cellForRowAt indexPath

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

    let item = array[indexPath.row]
    let url = URL.init(string: item["imageUrl"] as! String)!

    cell.myImage.image = nil
    DispatchQueue.global().async {
        let data = try! Data.init(contentsOf: url)
        DispatchQueue.main.async {

            let image = UIImage.init(data: data)!
            if let cell = tableView.cellForRow(at: indexPath) as? Cell, cell.myImage.image == nil {

                let multiplier = cell.myImage.bounds.width / image.size.width
                cell.heightConstraint.constant =  multiplier * image.size.height

                cell.myImage.image = image

                cell.layoutIfNeeded()
            }
        }
    }

    return cell
}

我在 GitHub 上有一个演示该问题的示例项目设置。 https://github.com/RishabhTayal/AutoTableViewPOC

最佳答案

我看了你的代码,你想通过自适应单元格高度来调整图片高度

self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.estimatedRowHeight = 1000

图像约束:

Trailing Space to: SuperView
Leading Space to: SuperView
Bottom Space to: SuperView
Top Space to: SuperView
Height Equals:199.5

日志打印会显示太多警告

Note that func heightForRow always executes first, then executes func cellForRowAt.

如果在func cellForRowAt中请求图片,获取高度后应该再次刷新cell。我也会去掉一个垂直约束,Bottom Space to: SuperView

我下载了 Kingfisher 并使用了一个属性来保存下载的图像。

var urlImages = [String : UIImage]()

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

        let item = array[indexPath.row]
        let urlString = item["imageUrl"] as! String
        let url = URL.init(string: urlString)!

        if let cacheImage = urlImages[urlString] {
            cell.myImage.image = cacheImage
            let height = self.view.bounds.size.width * (cacheImage.size.height / cacheImage.size.width)
            cell.imageHeightConstraint.constant = height
        }else{
            cell.myImage.kf.setImage(with: url, placeholder: nil, options: .none, progressBlock: nil) { result in

                switch result{
                case .success(let value):
                    let image = value.image
                    self.urlImages[urlString] = image

                    let height = self.view.bounds.size.width * (image.size.height / image.size.width)
                    cell.imageHeightConstraint.constant = height

                    tableView.reloadData()

                case .failure(let error):
                    print("error \(error)")
                }
            }
        }

        return cell
    }

刷新会先执行func heightForRowAt,现在像这样

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        let item = array[indexPath.row]
        let urlString = item["imageUrl"] as! String
        if let image = urlImages[urlString] {
            let height = self.view.bounds.size.width * (image.size.height / image.size.width)
            return height
        }
        return 44
    }

估计高度代码也需要去掉

关于ios - 带有异步 UIImageView 的自动布局 UITableViewCell 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57795313/

相关文章:

iOS - swift 3 - DispatchGroup

ios - 从 "More"菜单中删除 UITabBarController 上的默认向右滑动动画

swift - 电话号码的 NSURL 返回 nil

swift - 声明枚举路由器 Alamofire swift 3.0

ios - 自定义 UITableViewCell 重用问题中的 UISwitch

c++ - 在iOS上执行pthread_cancel时,堆中的内存会被释放吗?

ios - UIButton titleLabel 未显示居中对齐。

ios - 如何屏蔽和添加阴影到 UIView

ios - 如何 Hook UITableViewCell/UICollectionViewCell 的 init 方法?

iphone - 如何返回两个自定义的uitableviewcell