在 AutoLayout 中,您可以使用可视格式语言组合水平和垂直约束吗?

In AutoLayout can you combine both horizontal and vertical constraints using the Visual Format Language?

在我们很多地方的代码中,我一直看到这个...

containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":childView]))
containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":childView]))

这对我来说似乎是多余的。我想知道是否有办法将这些格式组合成一个字符串;像这样...

containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|;V:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":childView]))

所以这样的事情可能吗?

不,遗憾的是语法不允许这样做 - 请参阅 the docs

中的语法

具体来说,<orientation> H|V行表示orientation的值 可以是 HV 但不能两者都是。

程序化自动布局的一个很好的替代方法是使用开源 DSL 库 - 其中两个流行的例子是 Cartography and Snapkit

我都用过,发现它们比 VFL 更简单,也比底层的 Apple 更简洁 API

很抱歉你不能使用这个,但你可以试试这样的东西

let rr = UIView()

rr.backgroundColor = UIColor.red

self.view.addSubview(rr)

rr.translatesAutoresizingMaskIntoConstraints = false

["H:|-100-[rr]-100-|","V:|-100-[rr]-100-|"].forEach{NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: [=10=], options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["rr":rr]))}

评论:

  1. 您应该激活约束而不是将它们添加到视图中(自 iOS 8)。
  2. 您可以跳过整个 options: NSLayoutFormatOptions(rawValue: 0),因为这是默认值。
  3. VFL returns 一个约束数组,因此您可以将数组相加。

通过这些更改,我们得到了这行代码:

NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", metrics: nil, views: ["view":childView]) + NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", metrics: nil, views: ["view":childView]))