通过 Swift 中的代码自动布局适合父级

Auto-Layout fit to parent via code in Swift

我有一个视图正在通过代码创建并作为子视图添加到另一个视图。 新的超级视图可以随着时间的推移改变它的框架,我希望新创建的子视图相应地改变它的框架。 我如何在 Swift 中通过代码使用自动布局来做到这一点?

这是一个例子:

let view = UIView() // existing view

let subview = UIView()
subview.setTranslatesAutoresizingMaskIntoConstraints(false)

view.addSubview(subview)
view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: subview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: view, attribute: .Bottom, relatedBy: .Equal, toItem: subview, attribute: .Bottom, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: view, attribute: .Trailing, relatedBy: .Equal, toItem: subview, attribute: .Trailing, multiplier: 1.0, constant: 0.0))

正如@rjobidon 提到的,您应该使用以下代码 (Swift3)

    let view = UIView() // existing view

    let subview = UIView()
    subview.setTranslatesAutoresizingMaskIntoConstraints(false)

    view.addSubview(subview)

    NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: subview, attribute: .bottom, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: subview, attribute: .trailing, multiplier: 1.0, constant: 0.0).isActive = true

iOS13,swift5

首先,您添加这段代码

    subview.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(subview)

然后,在 iOS 的较新版本中有两种方法可以做到这一点。

  1. NSLayoutConstraintclass

    NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: subview, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1, constant: 0).isActive = true
    
  2. NSLayoutAnchor class(更简洁)

    subview.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    subview.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    subview.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    subview.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
    

无论哪种方式,在 iOS 8 及更高版本上,Apple 建议使用 isActive() 而不是直接向视图添加约束。

此外,我认为 NSLayoutAnchor 方法的目的是与 NSLayoutConstraint 相比更加简洁和可读。

您也可以像这样激活约束:

let view = UIView() // existing view

let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false

view.addSubview(subview)


NSLayoutConstraint.activate([
                view.leadingAnchor.constraint(equalTo: subview.leadingAnchor),
                view.trailingAnchor.constraint(equalTo: subview.trailingAnchor),
                view.topAnchor.constraint(equalTo: subview.topAnchor),
                view.bottomAnchor.constraint(equalTo: subview.bottomAnchor)
            ])