创建具有可变内容(包括 UICollectionView)的 UIScrollView 的最佳策略是什么?

What is the best strategy for creating a UIScrollView with variable contents including a UICollectionView?

我 运行 不时遇到这个问题,但仍然没有找到令人满意的解决方案。我正在尝试创建一个复杂的可滚动视图。考虑以下示例:

[UIView 1]
[UIView 2]
[UIView 3]
[UICollectionView]
[UIView 4]

在这种情况下,四个 UIView 中的任何一个都可以隐藏或可见。 UICollectionView 不应滚动,而应显示所有单元格。所有这五个视图都应该在一个滚动所有视图的 UIScrollView 中。

我还没有找到完成这项工作的秘诀。

选项 1] 在代码中完全手动布置内容。我知道这会起作用,但它非常不方便,因为它会影响子视图,而子视图本身就很复杂。

选项 2] 五个视图中的每一个都在一个 UICollectionView 单元格中,并且 UICollectionView 处理大小调整和滚动。我同样知道这会起作用,但完成它似乎需要很多开销。

选项 3] 将五个视图包装在一个 UIStackView 中。这似乎是这个问题最自然的解决方案,但它依赖于能够同时做三件事,而我还没有做到:

  1. 根据[可见]五个视图的高度设置stack view的高度。我试图通过从界面生成器链接到代码的高度约束来实现这一点。

  2. 将集合视图设置为具有基于其包含的单元格数量的可变高度。

  3. 将 UIScrollView 内容设置为与堆栈视图具有相同的高度。

到目前为止,我还没有找到使所有这些事情发生的正确约束集,这让我开始认为带有 UIStackView 的 UIScrollView 不是一个可行的解决方案问题。在我尝试过的所有方法中,我要么破坏了集合视图显示所有单元格的能力,要么我无法在滚动视图中访问整个堆栈视图(IE,它在底部之前被切断)。

关于解决此类问题的正确策略的想法? (提前致谢)

我肯定会选择选项 3。我遇到了一个相似但不同的层次结构(一个带有 UIImageView、UIStackView、UIButton 的表单,堆栈视图内部是两个文本字段、一个文本视图和一个 table 查看。

我给文本视图一个大于特定值的高度限制,然后使用 UITableView 的子类使其高度根据内容动态变化。我能够为 UICollectionView 创建一个类似的子类,你可能想用它来使你的集合视图高度动态化:

import UIKit

class DynamicHeightCollectionView: UICollectionView {
    override var contentSize: CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }
    
    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
    }
}

然后从情节提要中,确保您 select 集合视图,转到大小检查器,并将内部大小设置为占位符以避免情节提要警告。

这应该可以解决故事板中的所有布局问题,并有望奏效。