自动调整包含 UICollectionView 的 UITableViewCell

Auto-sizing UITableViewCell which contains UICollectionView

我在使用包含 UICollectionView 的自动调整 UITableViewCell 时遇到问题。视图层级大致是这样

UITableViewCell
-- Content View
---- Custom View
------ UIStackView (vertical)
--------- UILabel
--------- UICollectionView (vertical flow layout)

创建或重用 UITableViewCell 时,collectionView 会收到一个数据源,然后开始处理该数据源。我需要 collectionView 的所有单元格都显示在 tableViewCell 中,所以我在自定义视图中观察到 collectionView 内容大小的变化

    self.collectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.old, context: nil)

一旦 collectionView 完成呈现其内容,我读取其 contentSize 并相应地设置集合视图的高度约束。这很好用。

现在的问题是所有值都计算正确,但单元格大小在 tableView 中没有改变。控制台中没有自动布局错误或警告,因此我假设所有约束都是正确的。 stackView 中的标签也自动调整大小,这很好用。

我可以将有关 stackView 的新 contentSize 的信息一直传递到 TableViewController,但我不知道该调用什么来强制自动布局重新计算单个单元格的高度。

如果单元格中 collectionView 的高度约束与其内容大小不匹配,我在控制器级别调用 tableView.reloadData(),它就可以工作。但是会造成延迟,显然代价太大。

如果我将已更改的单元格传递给 tableView 并要求它仅重新加载单元格,tableView 找不到单元格的 indexPath(可能是因为它仍在屏幕外)。所以这个方法不行。

谢谢!

首先感谢大家的回复!

拔了两天头发,看来UITableViewCell layout not updating until cell is reused帮我解决了。

问题是缺少

    cell.layoutIfNeeded()

结束时
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

在这里你可以看到它现在的样子。设置就像原来的问题一样。

再次感谢大家的指点!

甚至认为这是一个已经回答的问题。但是我在这个 tutorial 中找到了根据 UICollectionView 高度大小调整 UITableViewCell 高度的简单方法。

UICollectionView 添加高度限制并在 UITableViewCell 中为其创建出口,并且不要忘记禁用 UICollectionView 滚动并将其流设置为垂直。

@IBOutlet weak var collectionViewHeight: NSLayoutConstraint!

UITableViewDelegate cellForRow 方法中使用这些

cell.frame = tableView.bounds

cell.collectionView.reloadData()

cell.layoutIfNeeded()

cell.collectionViewHeight.constant = cell.collectionView.collectionViewLayout.collectionViewContentSize.height

我可以说它工作得很好,不需要观察。

Link for full tutorial