iOS - 以编程方式使用自动布局将 UIView 定位在超级视图的中心

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14011395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:36:19  来源:igfitidea点击:

iOS - Position UIView in center of superview using Auto Layout programmatically

iphoneiosautolayout

提问by Rohan Agarwal

How do you programmatically set a UIView to be in the center of its superview using Auto Layout?

如何使用自动布局以编程方式将 UIView 设置为位于其超级视图的中心?

UIButton* viewObj = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewObj setTranslatesAutoresizingMaskIntoConstraints:NO];
[viewObj setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:viewObj];

NSLayoutConstraint* cn = [NSLayoutConstraint constraintWithItem:viewObj
                                                      attribute:NSLayoutAttributeCenterX
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeCenterX 
                                                     multiplier:1.0
                                                       constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj 
                                  attribute:NSLayoutAttributeCenterY
                                  relatedBy:NSLayoutRelationEqual 
                                     toItem:self.view
                                  attribute:NSLayoutAttributeCenterY
                                 multiplier:1.0
                                   constant:0];
[self.view addConstraint:cn];

The above code works for me for UIButton, but I'm having trouble replacing the first line with something that works for a UIView.

上面的代码适用于 UIButton,但我无法将第一行替换为适用于 UIView 的代码。

I've tried

我试过了

UIView* viewObj = [UIView alloc] initWithFrame:CGRectZero];

but the view does not show up in simulator.

但该视图未显示在模拟器中。

Any suggestions?

有什么建议?

Thanks!

谢谢!

采纳答案by Peter E

Since you asked this question in the context of using Auto Layout, the issue here is that a UIButton has an intrinsic size (communicated through the intrinsicContentSize method) that provides Auto Layout with information about width and height, but a UIView normally does not. So you need to add more constraints related to width and height.

由于您在使用自动布局的上下文中提出了这个问题,因此这里的问题是 UIButton 具有固有大小(通过 internalContentSize 方法进行通信),它为自动布局提供有关宽度和高度的信息,但 UIView 通常没有。所以你需要添加更多与宽度和高度相关的约束。

If you want your UIView to be a set size (say, 200x200), you could add these lines:

如果您希望 UIView 为固定大小(例如 200x200),您可以添加以下几行:

cn = [NSLayoutConstraint constraintWithItem:viewObj 
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual 
                                     toItem:nil
                                  attribute:NSLayoutAttributeNotAnAttribute 
                                 multiplier:1
                                   constant:200];
[viewObj addConstraint:cn];

cn = [NSLayoutConstraint constraintWithItem:viewObj
                                  attribute:NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:nil
                                  attribute:NSLayoutAttributeNotAnAttribute 
                                 multiplier:1 
                                   constant:200];
[viewObj addConstraint: cn];

Note that the toItem:argument is niland the second attribute is NSLayoutAttributeNotAnAttribute, because you aren't specifying the width and height relative to anything else. If you want the subview's height and width to be relative to the superview (say, 0.5), you could do this:

请注意,toItem:参数 isnil和第二个属性是NSLayoutAttributeNotAnAttribute,因为您没有指定相对于其他任何内容的宽度和高度。如果您希望子视图的高度和宽度相对于父视图(例如 0.5),您可以这样做:

cn = [NSLayoutConstraint constraintWithItem:viewObj
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeHeight 
                                 multiplier:0.5 
                                   constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
                                  attribute:NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeWidth
                                 multiplier:0.5
                                   constant:0];
[self.view addConstraint: cn];

回答by Imanou Petit

UIButton, UIImageView, UIlabeland UITextFieldcan automatically set their size according to their content properties. The width and height of a UIImageVieware set by the UIImageit may contain. The size of a UILabelwill depend on its text. The width and height of a UIButtonare defined by the title and the image it has (you can learn more about it with Intrinsic Content Size).

UIButton, UIImageView,UIlabel并且UITextField可以根据它们的内容属性自动设置它们的大小。a 的宽度和高度UIImageViewUIImage它可能包含的内容设置。a 的大小UILabel取决于它的文本。a 的宽度和高度UIButton由标题和它拥有的图像定义(您可以通过Intrinsic Content Size了解更多信息)。

Therefore, when you want to center a UIButton, a UILabel, a UITextFieldor a UIImageViewinside a UIViewwith auto layout, in almost all cases you don't have to create constraints for their width and height. You simply need to set horizontal and vertical constraints for them.

因此,当您希望使用自动布局将 a UIButton、 a UILabel、 aUITextField或 aUIImageView内部居中时UIView,几乎在所有情况下,您都不必为其宽度和高度创建约束。您只需要为它们设置水平和垂直约束。

However, with auto layout, a UIViewthat has no subviews can't rely on anything to set its size unless you provide it some arbitrary width and height constraints. And according to your needs, you can solve this in 3 different ways.

但是,对于自动布局,UIView没有子视图的a不能依赖任何东西来设置其大小,除非您为其提供一些任意的宽度和高度约束。根据您的需要,您可以通过 3 种不同的方式解决此问题。



The pure auto layout style

纯自动布局风格

Here, we set the width and height of our UIViewdirectly as auto layout constraints:

在这里,我们UIView直接将我们的宽度和高度设置为自动布局约束:

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = .redColor()
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    // Auto layout code using anchors (iOS9+)
    let horizontalConstraint = newView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor)
    let verticalConstraint = newView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor)
    let widthConstraint = newView.widthAnchor.constraintEqualToAnchor(nil, constant: 100)
    let heightConstraint = newView.heightAnchor.constraintEqualToAnchor(nil, constant: 100)
    NSLayoutConstraint.activateConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}


The autoresizing mask style

自动调整遮罩样式

Here, we initialize our UIViewwith its width and height, make its center and its superview's center equal and create some autoresizing masks. Then, we ask UIKit to translate those autoresizing masks into auto layout constraints:

在这里,我们UIView用它的宽度和高度初始化我们的,使它的中心和它的超级视图的中心相等,并创建一些自动调整大小的蒙版。然后,我们要求 UIKit 将这些自动调整大小的掩码转换为自动布局约束:

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
    newView.backgroundColor = .redColor()

    newView.center = CGPointMake(view.bounds.midX, view.bounds.midY)
    newView.autoresizingMask = [.FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin, .FlexibleBottomMargin]

    newView.translatesAutoresizingMaskIntoConstraints = true // default is true
    view.addSubview(newView)
}


The subclass style

子类样式

Here, we create a subclass of UIViewand override its intrinsicContentSize()method (declaration) so that it returns the desired size:

在这里,我们创建一个子类UIView并覆盖其intrinsicContentSize()方法(声明),以便它返回所需的大小:

import UIKit

class CustomView: UIView {
    override func intrinsicContentSize() -> CGSize {
        return CGSize(width: 100, height: 100)
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let newView = CustomView()
        newView.backgroundColor = .redColor()
        newView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(newView)

        let horizontalConstraint = NSLayoutConstraint(item: newView,
            attribute: .CenterX,
            relatedBy: .Equal,
            toItem: view,
            attribute: .CenterX,
            multiplier: 1,
            constant: 0)
        view.addConstraint(horizontalConstraint)
        let verticalConstraint = NSLayoutConstraint(item: newView,
            attribute: .CenterY,
            relatedBy: .Equal,
            toItem: view,
            attribute: .CenterY,
            multiplier: 1,
            constant: 0)
        view.addConstraint(verticalConstraint)
    }

}