锚固 (Anchorage)

Swift 4.2 + 5.0 CircleCI Version Platform Carthage compatible

一个轻量级的、直观的运算符和实用程序集合,用于简化 Auto Layout 代码。 Anchorage 直接构建于 NSLayoutAnchor API 之上。

每个表达式都作用于一个或多个 NSLayoutAnchor,并返回活动的 NSLayoutConstraint。 如果你想要非活动的约束,这里是如何操作的

用法

对齐

// Pin the button to 12 pt from the leading edge of its container
button.leadingAnchor == container.leadingAnchor + 12

// Pin the button to at least 12 pt from the trailing edge of its container
button.trailingAnchor <= container.trailingAnchor - 12

// Center one or both axes of a view
button.centerXAnchor == container.centerXAnchor
button.centerAnchors == container.centerAnchors

相对对齐

// Position a view to be centered at 2/3 of its container's width
view.centerXAnchor == 2 * container.trailingAnchor / 3

// Pin the top of a view at 25% of container's height
view.topAnchor == container.bottomAnchor / 4

尺寸调整

// Constrain a view's width to be at most 100 pt
view.widthAnchor <= 100

// Constraint a view to a fixed size
imageView.sizeAnchors == CGSize(width: 100, height: 200)

// Constrain two views to be the same size
imageView.sizeAnchors == view.sizeAnchors

// Constrain view to 4:3 aspect ratio
view.widthAnchor == 4 * view.heightAnchor / 3

组合锚点

使用此语法一次约束多个边缘

// Constrain the leading, trailing, top and bottom edges to be equal
imageView.edgeAnchors == container.edgeAnchors

// Inset the edges of a view from another view
let insets = UIEdgeInsets(top: 5, left: 10, bottom: 15, right: 20)
imageView.edgeAnchors == container.edgeAnchors + insets

// Inset the leading and trailing anchors by 10
imageView.horizontalAnchors >= container.horizontalAnchors + 10

// Inset the top and bottom anchors by 10
imageView.verticalAnchors >= container.verticalAnchors + 10

使用 leading 和 trailing

使用 leftAnchorrightAnchor 很少是正确的选择。为了鼓励这一点,horizontalAnchorsedgeAnchors 使用 leadingAnchortrailingAnchor 布局锚点。

使用内边距代替偏移

当约束 leading/trailing 或 top/bottom 时,更常见的是根据与边缘的内边距来工作,而不是在同一方向上偏移两个边缘。 构建表达式时,Anchorage 将翻转关系并反转轴远侧约束中的常量。 这使得表达式使用起来更加自然。

优先级

~ 用于指定任何 Anchorage 表达式产生的约束的优先级

// Align view 20 points from the center of its superview, with system-defined low priority
view.centerXAnchor == view.superview.centerXAnchor + 20 ~ .low

// Align view 20 points from the center of its superview, with (required - 1) priority
view.centerXAnchor == view.superview.centerXAnchor + 20 ~ .required - 1

// Align view 20 points from the center of its superview, with custom priority
view.centerXAnchor == view.superview.centerXAnchor + 20 ~ 752

布局优先级是一个具有以下值的枚举

存储约束

要存储由 Anchorage 创建的约束,只需将表达式分配给一个变量

// A single (active) NSLayoutConstraint
let topConstraint = (imageView.topAnchor == container.topAnchor)

// EdgeConstraints represents a collection of constraints
// You can retrieve the NSLayoutConstraints individually,
// or get an [NSLayoutConstraint] via .all, .horizontal, or .vertical
let edgeConstraints = (button.edgeAnchors == container.edgeAnchors).all

批量处理约束

默认情况下,Anchorage 返回活动的布局约束。 如果你更希望返回非活动的约束,以便与 NSLayoutConstraint.activate(_:) 方法一起使用以获得更好的性能,你可以这样做

let constraints = Anchorage.batch(active: false) {
    view1.widthAnchor == view2.widthAnchor
    view1.heightAnchor == view2.heightAnchor / 2 ~ .low
    // ... as many constraints as you want
}

// Later:
NSLayoutConstraint.activate(constraints)

如果你希望数组中的约束自动批量激活,也可以传递 active: true

Autoresizing Mask

Anchorage 将表达式左侧translatesAutoresizingMaskIntoConstraints 属性设置为 false,因此你永远不需要手动设置此属性。 请务必注意这一点,以防容器视图依赖于设置为 truetranslatesAutoresizingMaskIntoConstraints。 我们倾向于将子视图放在表达式的左侧,以避免这个问题,尤其是在约束到系统提供的视图时。

关于编译时间

Anchorage 重载了一些 Swift 运算符,这可能会导致编译时间增加。 你可以通过用 / 包围这些运算符来减少这种开销,如下所示

运算符 更快的替代方案
== /==/
<= /<=/
>= />=/

例如,view1.edgeAnchors == view2.edgeAnchors 将变为 view1.edgeAnchors /==/ view2.edgeAnchors

安装

CocoaPods

要使用 CocoaPods 将 Anchorage 集成到你的 Xcode 项目中,请在你的 Podfile 中指定它

pod 'Anchorage'

Carthage

要使用 Carthage 将 Anchorage 集成到你的 Xcode 项目中,请在你的 Cartfile 中指定它

github "Rightpoint/Anchorage"

运行 carthage update 以构建框架,并将构建的 Anchorage.framework 拖到你的 Xcode 项目中。

许可证

此代码和工具采用 MIT 许可证。 请参阅此存储库中的 LICENSE 文件。

欢迎任何想法和贡献!