垂直自动布局两个视图,动态高度对齐顶部

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 的底部对齐

iOS自动布局多个高度

ios自动布局视觉格式-对齐

两个具有不同字体大小的自动布局 UILabel:文本顶部对齐

在自动布局的情况下,IOS scrollview 模糊的可滚动内容高度