带有动态高度错误的异步图片设置为单元格

时间:2018-10-12 21:00:10

标签: ios swift asynchronous tableview cell

当我尝试下载图像并将其异步设置为具有动态高度的单元格时,我的应用程序遇到了错误。

错误的视频:https://youtu.be/nyfjCmc0_Yk


我一无所知:不明白为什么会这样。我保存了单元格的高度,以防止出现跳动问题和东西,甚至在设置图像后甚至更新了单元格的高度。


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {



            var post : Post
            var cell : PostCell
            post = Posts.shared.post(indexPath: indexPath)

            // I REMOVED SOME NOT IMPORTANT PARTS OF THE CODE 
            // (like setting the text, etc)

            if post.images.count > 0 {
                // Images is attached to the post

                cell.postImageView.sd_setImage(with: URL(string: appSettings.url + "/resources/img/posts/" + post.images[0]), placeholderImage: nil, options: [.avoidAutoSetImage]) { (image, error, type, url) in
                    if let error = error {
                        // placeholder
                        return
                    }

                    DispatchQueue.main.async {
                        let cgRect = image!.contentClippingRect(maxWidth: 300, maxHeight: 400)
                        cell.postImageView.isHidden = false

                        cell.postImageWidthConstraint.constant = cgRect.width
                        cell.postImageViewHeightConstraint.constant = cgRect.height

                        cell.postImageView.image = image

                        cell.layoutIfNeeded()
                        self.cellHeights[indexPath] = cell.frame.size.height

                    }
                }


            } else {
                // No image is attached to the post
                cell.postImageViewHeightConstraint.constant = 0
                cell.postImageWidthConstraint.constant = 0
                cell.postImageView.isHidden = true
            }
            return cell


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

        cell.layoutIfNeeded()

    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if cellHeights[indexPath] != nil {
            return CGFloat(Float(cellHeights[indexPath] ?? 0.0))
        }
        else {
            return UITableViewAutomaticDimension
        }
    }

我尝试调用tableView.beginUpdates() tableView.endUpdates(),它在一开始就解决了问题,但是滚动时会产生怪异的错误:

https://youtu.be/932Kp0p0gfs

(在表格视图中随机出现在图像的一小部分)

然后向上滚动时,它会跳到帖子的开头。可能是由于高度值不正确吗?

我该怎么办?

1 个答案:

答案 0 :(得分:1)

如果要计算UIImage数据的高度和宽度并将这些值分配为UIImageView的约束常数,尤其是在单元格中,肯定会出现此类错误。

解决方案?使您的数据源/服务器具有计算出的宽度和高度,并避免自己计算。意味着在每个Post对象中,应该有一个准备好的宽度和高度值。这样速度更快,并且解决了您的问题(请参阅我的这个可爱的个人快速项目:https://itunes.apple.com/us/app/catlitter-daily-dose-of-cats/id1366205944?ls=1&mt=8

此外,我还从一些知名公司(如Facebook)提供的一些公共API中了解到(每个图像都有其计算出的尺寸)。

我希望这会有所帮助。