【问题标题】:Make tableview cell height dynamically after download image from server从服务器下载图像后动态制作表格视图单元格高度
【发布时间】:2018-04-16 07:04:43
【问题描述】:

我有一个单元格,我现在在其中显示从服务器下载的图像。现在我显示具有静态高度的图像,但现在我想像 facebook 和 instagram 一样制作动态图像。例如,如果我上传图像 320 * 100,那么我的单元格需要变为 300 * 100。如果需要,还建议服务器端更改 我正在使用 afnetworking 图像加载类。

这是我的细胞设计。

编辑: 我尝试了给定的解决方案,但现在的问题是当第二次进入 cellforindexpath 方法时,单元格会随着混蛋调整大小。这只会发生在第一个单元格中。

【问题讨论】:

  • tableview 还是 collectionview?
  • @AnshadRasheed 在标题中提到了 Tableview。
  • @chirag 看看这个帖子stackoverflow.com/questions/42163132/…
  • 图像标记为collectionview
  • @AnshadRasheed 我也使用了集合视图,因为有显示图像的分页。

标签: ios swift uitableview uitableviewautomaticdimension


【解决方案1】:

我已经完成了类似的任务,在桌子上显示图像并调整 tableview 单元格的大小,以便图像沿全屏宽度显示

IndexPath 处的行高

var cachedHeight = [IndexPath : CGFloat]()
    override func tableView(_ tableView: UITableView, heightForRowAtindexPath: IndexPath) -> CGFloat {

    let default_height : CGFloat = 332.0

    // lookup for cached height
    if let height = cachedHeight[indexPath]{
        return height
    }

    // no cached height found
    // so now try for image so that cached can be calculated and cached
    let cache : SDImageCache = SDImageCache.shared()
    let image : UIImage? = cache.imageFromDiskCache(forKey: self.viewModel?.getProductImage(of: indexPath.row, at: 0))

    if let image = image{
        let baseHeight : CGFloat = CGFloat(332 - 224)   // cell height - image view height
        let imageWidth = self.tableView.frame.size.width
        let imageHeight = image.size.height * imageWidth / image.size.width

        cachedHeight[indexPath] = imageHeight + baseHeight
        return cachedHeight[indexPath]!
    }

    //
    //  even if the image is not found, then
    //  return the default height
    //
    return default_height
}

IndexPath 处的行单元格

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

    let sdCache = SDImageCache.shared()
    let cell = tableView.dequeueReusableCell(withIdentifier: "MyXYZCell", for: indexPath) as! AuctionListTableViewCell
    let imageURL = self.viewModel?.getProductImage(of: indexPath.row, at: 0)

    if let imageURL = imageURL {
        if (sdCache.imageFromCache(forKey: imageURL) != nil) {
            //
            //  image data already persist on disk,
            //  cell height update required
            //
            cell.auctionImageView.sd_setImage(with: URL.init(string: imageURL), completed: nil)
        }
        else
        {
            cell.auctionImageView.sd_setImage(with: URL.init(string: imageURL), completed: { (image, err, cacheType, url) in
                self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
            })
        }
    }

    //other cell customization code

    return cell
}

我用过SDWebImage。你可以使用它,或者在AFNetworking中找到类似的api。

主题演讲:

  1. 这里cachedHeight用于缓存IndexPath索引的单元格的高度,因为从磁盘读取图像是安静的I/O穷举任务,导致表格视图滚动滞后。
  2. heightForRow中,我检查了图像是否在缓存中,如果在缓存中,则计算高度,将其存储到cachedHeight中,否则返回默认高度。 (我的默认高度是为占位符图像计算的)
  3. cellForRowAtIndexPath 中我检查了图像是否在缓存中。如果图像在缓存中,则不需要重新加载,因为已经计算了高度。否则我会尝试网络提取,当提取完成后我请求 tableview 重新加载该单元格。

希望对您有所帮助,祝您编码愉快。

【讨论】:

  • 是的,我尝试了您的解决方案,但我有一个问题,您计算联系人的高度,但我使用了 UITableViewAutomaticDimension,所以第一次以默认高度加载图像,当它重新加载时,它会变得更大。那么有什么办法可以阻止这个混蛋。
  • 停止抽搐使用self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic) 并转到界面构建器,选择表格视图,在size inspector 部分取消选中Row height 自动选项并取消选中Estimate 选项。另一件事,请说明您是如何使用UITableViewAutomaticDimension 的。我的意思是你是在哪里以及如何设置它的?
  • 终于完成了,当我在 cellForRow 中设置集合视图的高度时,抽搐消失了,并且魅力它正在工作
【解决方案2】:

我已经解决了这个问题。 如果您必须使图像视图的高度和宽度动态化,则要求服务器在 API 响应中发送图像宽度和高度。 一旦你得到两者,根据图像宽度和屏幕宽度计算图像高度。 采取图像高度的约束。并将计算出的高度分配给图像高度约束。

要计算图像高度,请使用以下公式:-

imageHeight =  (screen_width * actual_image_height) / actual_image_width

【讨论】: