【问题标题】:Autolayout UITableViewCell with async UIImageView not working具有异步 UIImageView 的自动布局 UITableViewCell 不起作用
【发布时间】:2019-09-04 20:33:47
【问题描述】:

我有一个UITableView,配置非常基本。 tableview 单元格只包含一个UIImageView

查看层次结构:

我想在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

【问题讨论】:

    标签: ios swift uitableview autolayout


    【解决方案1】:

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

    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
    

    日志打印会显示太多警告

    请注意,func heightForRow 总是先执行,然后再执行 func cellForRowAt

    如果你在func cellForRowAt请求图片,你应该在得到高度后再次刷新单元格。我还将删除一个垂直约束,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
        }
    

    估计身高代码也需要去掉

    【讨论】:

      猜你喜欢
      • 2019-11-30
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2016-05-04
      • 2021-10-12
      • 2015-04-22
      • 1970-01-01
      相关资源
      最近更新 更多