【问题标题】:Auto-sizing UITableViewCell which contains UICollectionView自动调整包含 UICollectionView 的 UITableViewCell
【发布时间】:2019-07-29 04:28:17
【问题描述】:

我在使用包含 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 并相应地设置 collection view 的高度约束。这很好用。

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

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

如果我在控制器级别调用tableView.reloadData(),如果单元格中collectionView 的高度约束与其内容大小不匹配,它确实有效。但这会导致延迟,而且显然太昂贵了。

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

谢谢!

【问题讨论】:

  • 请提供预期的 UI 屏幕截图。我认为单个滚动视图是可能的,你不需要嵌套两个滚动视图。
  • @SPatel 没有两个滚动视图。 tableView 有 scrollView,collectionView 的大小可以显示所有单元格,所以它不会滚动。
  • 我也偶然发现了这种情况,但我意识到执行此操作可能很繁重,因为它可能并不总是可以在 tableview 单元之前进行 collectionview 单元格的大小布局。在大多数用例场景中,您可以通过提前计算它们来维护这些高度的数据源,因为我们只会指定 collectionview 单元格大小。
  • @Georg 我个人建议你尽可能不要使用嵌套滚动视图。
  • 除此之外,想指出你在嵌套滚动视图时可能会陷入常见的错误,你应该在 tablview 的 dequeue 方法中调用 collectionview.reloadData() ,因为在重用表格单元格时,collectionview 会重用它的不调用自己的 dequeue 方法。这会有所帮助 - ashfurrow.com/blog/…

标签: ios swift uitableview uicollectionview autolayout


【解决方案1】:

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

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

@IBOutlet weak var collectionViewHeight: NSLayoutConstraint!

UITableViewDelegatecellForRow 方法中使用这些

cell.frame = tableView.bounds

cell.collectionView.reloadData()

cell.layoutIfNeeded()

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

我可以说它就像魅力一样工作,不需要观察。

Link for full tutorial

【讨论】:

    【解决方案2】:

    首先感谢大家的回复!

    在拔掉我的头发两天后,看起来UITableViewCell layout not updating until cell is reused 为我解决了这个问题。

    问题是丢失

        cell.layoutIfNeeded()
    

    在结尾

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

    在这里你可以看到它现在的样子。设置与原始问题中的一样。

    再次感谢大家的指点!

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 2018-05-18
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    相关资源
    最近更新 更多