在 Auto Layout 的视觉格式语言中使用可选值

Posted

技术标签:

【中文标题】在 Auto Layout 的视觉格式语言中使用可选值【英文标题】:Using optional values in Auto Layout's visual format language 【发布时间】:2020-04-29 15:35:56 【问题描述】:

我目前有一个受以下视觉格式约束的视图:

let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[myView]", options: [], views: ["myView": myView]
view.addConstraints(constraints)

我正在引入一个可选值,如果在添加此约束时存在,则应将其用作此视觉格式中的间距。我目前正在这样做:

let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[myView]", options: [], views: ["myView": myView]
if let constraint = constraints.first, let spacing = optionalSpacing 
    constraint.constant = -spacing

view.addConstraints(constraints)

但这似乎有点不雅,它扼杀了视觉格式的主要好处,因为您无法一眼看出约束是如何工作的。

我还可以根据添加此约束时我的值是否为 nil 来更新可视格式字符串和指标:

var format: String
var metrics: [String: CGFloat]?
if let spacing = optionalSpacing 
    format = "V:|-(spacing)-[myView]"
    metrics = ["spacing": spacing]
 else 
    format = "V:|[myView]"

let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[myView]", options: [], metrics: metrics, views: ["myView": myView]

但这很丑。

我想知道是否有人以前遇到过类似的问题,他们通常如何解决?我没有在网上看到很多关于如何处理格式字符串中的可选值的文档。我假设我不能在不首先检查 optionalSpacing 是否为非 nil 的情况下创建具有可选值的格式字符串(例如 "V:|-(optionalSpacing)-[myView]"),因为 metrics 字典具有非可选值。

【问题讨论】:

您没有看到很多文档,因为 Visual Format Language 是一个非常早期的尝试,它使繁琐的约束语法变得更容易。然而,现在(在我看来)它是如此易于使用的约束,以至于不再需要 VFL(无论如何一开始它都非常有限)。 【参考方案1】:

您可以使用nil 合并运算符?? 来简化此操作:

let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(spacing)-[myView]",
                                                 metrics: ["spacing": optionalSpacing ?? 0],
                                                 views: ["myView": myView])

view.addConstraints(constraints)   // or, perhaps better, `NSLayoutConstraint.activate(constraints)`

这消除了对if 语句的需要。


或者,如果您想使用更现代的锚语法:

NSLayoutConstraint.activate([
    myView.topAnchor.constraint(equalTo: view.topAnchor, constant: optionalSpacing ?? 0)
])

【讨论】:

以上是关于在 Auto Layout 的视觉格式语言中使用可选值的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在Interface Builder中为Auto Layout Constraints添加标识符?

使用 Auto Layout 改变 UIButtons 的 Column 布局

Debugging Auto Layout

使用视觉格式化语言在代码中自动布局 UIViewController

设置视觉格式语言时 iAutoLayout 崩溃

使用视觉格式语言的 UIButtons 之间的等间距