26

如何使用 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];

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

我试过了

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

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

有什么建议么?

谢谢!

4

2 回答 2

21

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

如果你希望你的 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];

请注意,toItem:参数是nil,第二个属性是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];
于 2012-12-23T15:02:16.603 回答
7

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

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

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


纯自动布局风格

在这里,我们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])
}

自动调整大小的蒙版样式

在这里,我们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)
}

子类风格

在这里,我们创建一个子类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)
    }
    
}
于 2015-12-27T18:01:36.777 回答