设计 UIView 使其可以根据内容高度动态更改其高度

Design UIView so that it can dynamically change its height based on the content height

XIB 文件中,我有一个 CustomView 与同名的 class 相关。

查看内容很简单。

有一个垂直 stackview,在 stackview 里面有两个 labelsstackview 与包含它的视图垂直对齐:

第一个标签(标题)包含静态文本(总是几个字符)。 第二个标签(副标题)可以有可变长度的文本。

我将此 CustomView 与其他类似视图一起添加为 Content View 的子视图,因为它是一个“行”。

for i in 0...aViews.count {

   var v = CustomView(frame: CGRect(x: 0, y: _y, width: 320, height: 100))
   v.labelText = "my long label text ..."
   contentView.addSubview(v)
   // ...
}

你可以想象,标题标签应该有一个固定的位置(顶部和左侧),即不能有一个标题从10点开始并且另一个在 14 岁。

我必须承认,我天真地认为标签的位置会自动管理,因为我垂直对齐了 stackview。我错了,我没有发现任何问题,直到他们告诉我第二个标签,副标题,可以包含不止一行。

我直接在storyboard中给标签加了行,结果发现:

  1. stackview 的容器不会根据其内容的 height 更改其 height

  2. “固定”元素的位置可能垂直居中但不是固定的;

我需要的是:

这可能吗?我应该如何设计我的视图?

我认为您混合了外部视图的绝对定位(即手动设置框架)和对其内部组件使用自动布局约束,并且错误地期望动态自动布局部分以某种方式 "reach all the way up" 到外部视图。对于自动布局,您需要一直使用自动布局,包括 CustomViewscontentView.

中的定位方式

如果出于某种原因你不想为此使用 TableView 或 CollectionView,你也可以,例如,尝试将你的 CustomViews 作为排列的子视图添加到具有 top/bottom/leading/trailing 约束到 contentView,然后将 CustomView 的 "Align Center Y" 约束替换为 "Align Top" 和 "Align Bottom" 约束,以实际允许标签从 "push"里面如果他们需要更多的垂直 space.

编辑 这里有一个快速草图来说明该设置:

编辑 2 这里有几个屏幕截图可以进一步说明。使用这样的基本布局:

运行时结果如下所示:

请注意,UIStackViews 在本例中使用 "Equal Spacing" Distribution。如果您想以编程方式创建和添加 CustomView,请使用 StackView 的 func addArrangedSubview(_ view: UIView)

祝你好运!

好的 - 看看你的项目,你离得不远了......只是几个关键项目。

  1. 在您的 CustomView.xib 中,您在 Fixed LabelDate Label 之间没有任何限制。结果是 Date Label 从视图底部向上 增长,没有任何东西可以阻止它。

  2. 同样在您的 CustomView.xib 中,您将 Fixed Label 限制在后缘...我假设您希望它与 Date Label[ 左对齐=23=]

  3. 创建 CustomView 时,您将高度限制设置为 100 -- 这违背了允许内容确定大小的目的。

  4. 在 CustomView class 中,您已将 contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 注释掉。那条线应该在那里。

  5. 在您的视图控制器中,您向 contentView 添加了低优先级的高度限制。最好的选择是将其设为占位符约束(双击约束,然后 select 占位符复选框)。这样,约束在 运行 时被移除,但在设计期间存在(故事板不会抱怨)。

  6. 您正在做一些其他不必要的事情 - 可能您正在尝试不同的东西来让它工作。

  7. 视图设置(添加您的视图)最好在 viewDidLoad() 中完成 -- 绝对不会viewDidLayoutSubviews()[=23 中完成=]

  8. 我猜想,在您的 CustomView 中,您 可能 想要限制 Date Label 前导和拖尾,允许它根据设备宽度水平拉伸...但我将其保留在 200。

如果您能遵循该信息,您应该能够解决问题。但是,我把这个项目作为一个 GitHub 存储库给你,这样你就可以得到它的 "working" 状态,这样你就可以看到变化。

这是回购的 link:https://github.com/DonMag/ATester2

结果如下:

向上滚动一点: