简体   繁体   English

如何在大于或等于约束的超级视图中居中两个视图

[英]How to center two views in super view with greater than or equal to constraints

I made an example ViewController with two Labels to highlight my issue.我制作了一个带有两个标签的示例 ViewController 来突出我的问题。 The goal is to vertically separate the labels by 10, and then center them vertically using greater than or equal to constraints.目标是将标签垂直分隔 10,然后使用大于或等于约束将它们垂直居中。 I'm using visual format, but this should apply if I setup my constraints like view.topAnchor.constraint(greaterThan... . I also have two constraints to horizontally layout the labels我使用的是视觉格式,但是如果我设置了我的约束,比如view.topAnchor.constraint(greaterThan... 。我也有两个约束来水平布局标签

My ViewController:我的视图控制器:

class myVC: UIViewController {
    lazy var titleLabel: UILabel = {
        let l = UILabel(frame: .zero)
        l.translatesAutoresizingMaskIntoConstraints = false
        l.text = "Hello World"
        l.font = .systemFont(ofSize: 50)
        l.textColor = .black
        return l
    }()

    lazy var descLabel: UILabel = {
        let l = UILabel(frame: .zero)
        l.translatesAutoresizingMaskIntoConstraints = false
        l.text = "description"
        l.font = .systemFont(ofSize: 35)
        l.textColor = .gray
        return l
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .yellow
        view.addSubview(titleLabel)
        view.addSubview(descLabel)
        titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        descLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor).isActive = true
        NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|", options: .init(), metrics: nil, views: ["titleLabel": titleLabel, "descLabel": descLabel]))
    }

}

This results in这导致错误的约束 . . From my understanding, this SHOULD separate the views by 10 pts, and center the labels vertically because in the format "V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|"根据我的理解,这应该将视图分隔 10 pts,并将标签垂直居中,因为格式为"V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|" I say that the distance between the Title Label's top and the superView's top should be at least (greaterThanOrEqualTo) 50, and the distance between the description Label's bottom and the superView's bottom should be at least 50. What should my top and bottom constraints look like if I want to center the two labels vertically?我说Title Label的顶部和superView的顶部之间的距离应该至少是(greaterThanOrEqualTo) 50,描述Label的底部和superView的底部之间的距离应该至少是50。我的顶部和底部约束应该是什么样的如果我想垂直居中两个标签?

Yes, I realize I can just set vertical and horizontal centers, but this is an example I made for a problem I can't use those for.是的,我意识到我只能设置垂直和水平中心,但这是我为无法使用它们的问题而制作的示例。 I need to be able to center the View with greater(or less) than or equal to constraints.我需要能够以大于(或小于)大于或等于约束的方式将视图居中。

It's very difficult to center elements using VFL.使用 VFL 使元素居中非常困难。

It's also difficult to center two elements unless they are embedded in a UIView or a UIStackView .除非将两个元素嵌入UIViewUIStackView否则它们也很难UIStackView

Here is one option by embedding the labels in a "container" UIView :这是将标签嵌入“容器” UIView一种选择:

class MyVC: UIViewController {
    lazy var titleLabel: UILabel = {
        let l = UILabel(frame: .zero)
        l.translatesAutoresizingMaskIntoConstraints = false
        l.text = "Hello World"
        l.font = .systemFont(ofSize: 50)
        l.textColor = .black

        // center the text in the label - change to .left if desired
        l.textAlignment = .center

        return l
    }()

    lazy var descLabel: UILabel = {
        let l = UILabel(frame: .zero)
        l.translatesAutoresizingMaskIntoConstraints = false
        l.text = "description"
        l.font = .systemFont(ofSize: 35)
        l.textColor = .gray

        // center the text in the label - change to .left if desired
        l.textAlignment = .center

        return l
    }()

    lazy var containerView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .yellow

        // give the labels and containerView background colors to make it easy to see the layout
        titleLabel.backgroundColor = .green
        descLabel.backgroundColor = .cyan
        containerView.backgroundColor = .blue

        // add containerView to view
        view.addSubview(containerView)

        // add labels to containerView
        containerView.addSubview(titleLabel)
        containerView.addSubview(descLabel)

        NSLayoutConstraint.activate([

            // constrain titleLabel Top to containerView Top
            titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor),

            // constrain titleLabel Leading and Trailing to containerView Leading and Trailing
            titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),

            // constrain descLabel Leading and Trailing to containerView Leading and Trailing
            descLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            descLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),

            // constrain descLabel Bottom to containerView Bottom
            descLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),

            // constrain descLabel Top 10-pts from titleLabel Bottom
            descLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10.0),

            // constrain containerView centered horizontally and vertically
            containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor),

        ])

    }

}

Result:结果:

在此处输入图片说明

This can be achieved easily by using stackview.这可以通过使用 stackview 轻松实现。 Add both the labels in stackview and center it vertically in the superview with all other constraints(top, leading, bottom, trailing).在 stackview 中添加两个标签,并在所有其他约束(顶部、前导、底部、尾部)中将其垂直居中。 Here is the sample code of view controller for your use-case.这是您的用例的视图控制器的示例代码。

class ViewController: UIViewController {

    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "Hello \nWorld"
        label.font = .systemFont(ofSize: 50)
        label.backgroundColor = .orange
        label.numberOfLines = 0
        label.textColor = .black
        return label
    }()

    lazy var descLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "a\n b\n c\n"
        label.font = .systemFont(ofSize: 35)
        label.backgroundColor = .green
        label.numberOfLines = 0
        label.textColor = .gray
        return label
    }()

    lazy var contentView: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.spacing = 10
        stackView.distribution = .fill
        return stackView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.white

        contentView.addArrangedSubview(titleLabel)
        contentView.addArrangedSubview(descLabel)
        self.view.addSubview(contentView)

        let constraints = [
            contentView.topAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.topAnchor),
            contentView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            contentView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor)
        ]
        NSLayoutConstraint.activate(constraints)

    }
}

The above code will result this view and it goes on to take the top and buttom space until it meets the safeArea.上面的代码将产生这个视图,它继续占据顶部和底部空间,直到它遇到安全区域。 Moreover you can set the vertical content hugging and compression resistance priority to control which label to expand or shrink.此外,您可以设置垂直内容拥抱和压缩阻力优先级来控制扩展或收缩哪个标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用大于或等于约束设置 tableViewCell 高度 - Setting tableViewCell height with greater than or equal to constraints iOS 9限制小于或等于X &amp;&amp;大于或等于Y - iOS 9 Constraints Less than or Equal X && Greater than or Equal Y 如何使用程序约束将两个文本视图堆叠+居中? - How to stack + center two text views using programatic constraints? 如何在不使布局不明确的情况下使用大于或等于对iOS AutoLayout约束进行编程? - How can I program iOS AutoLayout constraints using Greater Than or Equal without making the layout ambiguous? 无法使用约束将故事板上的两个视图居中-iOS - Unable to center two views on Storyboard with Constraints - iOS 在超级视图中嵌入视图而不会丢失自动布局约束 - Embed Views in super view without losing autolayout constraints 自动布局(约束)中心2在父视图中并排显示 - Auto Layout (Constraints) Center 2 side by side views in a parent view 如何使用view.frame和view.center居中两个视图 - How to center two views using view.frame and view.center 如何使用约束将两个视图固定在一起 - How to pin two views together using constraints 如何使用约束添加两个视图 - How to add two views on each other with constraints
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM