如何以编程方式布局故事板上的视图?

How do I layout view which is on storyboard programmatically?

我尝试在故事板上的视图上通过视觉格式语言以编程方式使用自动布局,但失败了。代码如下: (顺便说一句,显示bView的storyboard并不重要,所以我没有上传storyboard的图片。我也没有在storyboard上设置任何约束。)

class ViewController: UIViewController {

    @IBOutlet var bView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        bView.translatesAutoresizingMaskIntoConstraints = false
        var allConstraints = [NSLayoutConstraint]()
        let vC =  NSLayoutConstraint.constraintsWithVisualFormat("V:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
        let hC = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
        allConstraints += vC
        allConstraints += hC
        NSLayoutConstraint.activateConstraints(allConstraints)
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
    }
}

但是执行的时候报错:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format: Unable to interpret '|' character, because the related view doesn't have a superview V:|-[bView]-| ^'

我想也许 superView(viewController 的视图)确实添加到了主窗口上。所以我试图通过将代码移动到 viewWillLayoutSubviews() 来解决这个问题。如下:

class ViewController: UIViewController {

    @IBOutlet var bView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        bView.translatesAutoresizingMaskIntoConstraints = false
        var allConstraints = [NSLayoutConstraint]()
        let vC =  NSLayoutConstraint.constraintsWithVisualFormat("V:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
        let hC = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
        allConstraints += vC
        allConstraints += hC
        NSLayoutConstraint.activateConstraints(allConstraints)
    }
}

然后它显示了一个非常有趣的错误结果。

那么,我如何以编程方式布局故事板上的视图?


而且,还有一个有趣的结果是这样的: (与问题没有直接关系,大家可以试试看!)

使用代码:

class ViewController: UIViewController {

    @IBOutlet var bView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        bView.translatesAutoresizingMaskIntoConstraints = false
    }
}

如果您试图限制蓝色矩形,那么您的第一个问题是您的 bView 插座错误地连接到您的顶层视图(白色背景)。在 Connections Inspector 中删除该连接,然后将蓝色视图连接到 bView

如果您在 Interface Builder 中添加一个视图,但不给它任何约束,那么 Xcode 将在构建时添加 4 个约束。如果单击您的视图,您将在 Size Inspector 中看到以下消息:

The selected views have no constraints. At build time, explicit left, top, width, and height constraints will be generated for the view.

那么,您的观点已经完全明确了。如果您在代码中添加任何更多约束,您将产生冲突。

那么,如何在代码中为 Storyboard 中布局的视图添加约束?您需要执行以下操作:

  1. 在 Storyboard 中为左侧、顶部、宽度和高度添加显式约束。

  2. Size Inspector 中编辑这 4 个约束并选中 Placeholder [] Remove at build time 旁边的复选框].

然后,这 4 个约束将在构建时删除,使视图没有约束。现在您的代码可以自由添加约束了。