垂直自动布局两个视图,动态高度对齐顶部
Posted
技术标签:
【中文标题】垂直自动布局两个视图,动态高度对齐顶部【英文标题】:Autolayout two views vertically with dynamic height aligned top 【发布时间】:2013-11-22 11:25:53 【问题描述】:我有两个可以是动态高度的视图。 取决于内容 view1 或 view2 是最高的。
最高视图应确定到 view3 的距离。
在我当前的实现中,view1 和 view2 对 view3 的 x 像素都有一个约束。但问题是 view1 和 view2 总是相同的高度(所有内容都不会对齐顶部)
【问题讨论】:
一些澄清:当你说最高时,你的意思是最高的(所以视图 1 和视图 2 的高度可以独立变化)?并且从最高视图(1 或 2)到视图 3 的距离应该是恒定的? 是的 view1 和 view2 的高度可以独立变化。从最高视图(1 或 2)到 view3 的高度应该是一个常数。 【参考方案1】:试试这个。确保视图 1 和 2 对超级视图的顶部和侧面(或固定宽度,无论在水平方向上固定视图所采取的任何措施)都有一些约束。假设您希望与底部视图的距离为 30。为视图 1 设置一个约束,以查看 =30 的视图 3,优先级为 200,另一个 >=30,优先级为 1000(默认)。视图 2 应该只需要一个约束即可以 1000 优先级查看 >=30 的 3 个。
低优先级约束(200)最初将固定视图 3 的位置,但如果视图 2 展开,视图 3 将向下移动,并且足够低,视图 1 的默认内容拥抱优先级将如果不需要根据其文本大小,请阻止其扩展其高度。
【讨论】:
谢谢,我正朝着你的答案方向前进,但我没有在视图 1 和 3 之间使用两个垂直约束。 我找不到您所描述内容的良好文档。您能否提供您在此处推荐的约束的代码示例?我知道你已经有多久没有回答这个问题了,但我遇到了类似的情况,我想不出一个好的解决方案。 @Matt,书面文档没有详细介绍,因此您应该查看有关自动布局的 WWDC 2012 视频(有 3 个)以获取更多信息。如果此答案没有为您提供足够的详细信息来解决您的问题,您应该提出自己的问题。如果没有更多信息,我真的不知道我会向您展示什么代码。 谢谢。发表评论几分钟后,我找到了 VFL here 的文档。它有所帮助,但无法回答我所有的问题。 rdelmar,您认为与您的回答类似的内容是否可以应用于我的问题***.com/questions/31658526/…?【参考方案2】:迅速
import SnapKit
view3.snp.makeConstraints
$0.top.greaterThanOrEqualTo(view1.snp.bottom).offset(30)
$0.top.greaterThanOrEqualTo(view2.snp.bottom).offset(30)
$0.left.right.equalTo(0)
$0.height.equalTo(50)
【讨论】:
【参考方案3】:其实有两种方式
-
有约束(如 rdelmar 所述)
class MyViewController: ViewController
let view1 = View()
let view2 = View()
let view3 = View()
override func buildUI()
super.buildUI()
body
view1
.edgesToSuperview(top: 16, leading: 16)
view2
.edgesToSuperview(top: 16, trailing: -16)
.width(to: view1)
.leadingTo(view1, 16)
view3
.topTo(view1, 30 ! 200) // 200 is priority, ! is priority operator
.topTo(view2, >=30)
.edgesToSuperview(leading: 16, trailing: -16, bottom: -16)
我不确定 =30 和 200 的优先级,也许它应该 >=30 与 view2 一样,但您可以通过 Live preview 轻松搞定
-
使用 StackViews
class MyViewController: ViewController
override func buildUI()
super.buildUI()
body
VStack
HStack
View() // view 1
View() // view 2
.distribution(.fillEqually) // to make view 1&2 width equally
.alignment(.top)
Space() // flexible space
VSpace(30) // fixed 30pt height space
View() // view 3
.edgesToSuperview()
所有示例都使用了很棒的UIKitPlus 库
【讨论】:
【参考方案4】:接受的答案对我不起作用(尽管它确实让我走上了正确的道路)。在我的情况下,视图 1 或视图 2 可以是任意大小,并且视图 3 必须低于最高的。这段代码让它工作了,但我必须说我发现自动布局非常不直观:
let view3TopAnchor1 = statusL.topAnchor.constraint(greaterThanOrEqualTo: view1.bottomAnchor, constant: 10.0)
view3TopAnchor1.priority = UILayoutPriority(100)
view3TopAnchor1.isActive = true
let view3TopAnchor2 = statusL.topAnchor.constraint(greaterThanOrEqualTo: view2.bottomAnchor, constant: 10.0)
view3TopAnchor2.priority = UILayoutPriority(100)
view3TopAnchor2.isActive = true
view1.setContentHuggingPriority(UILayoutPriority(101), for: .vertical)
view2.setContentHuggingPriority(UILayoutPriority(101), for: .vertical)
【讨论】:
【参考方案5】:float yPos = MAX(view1.frame.size.height,view2.frame.size.height);
view3.frame.origin.y = view1.frame.origin.y + maxHeight;
【讨论】:
使用自动布局时无法更改框架。我考虑过根据内容制作自定义约束。以上是关于垂直自动布局两个视图,动态高度对齐顶部的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 具有嵌入式垂直堆栈视图设置,具有自动布局和动态高度
如何使用自动布局将两个具有动态高度的 UILabel 与 UICollectionViewCell 的底部对齐