一个轻量级的、直观的运算符和实用程序集合,用于简化 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
使用 leftAnchor
和 rightAnchor
很少是正确的选择。为了鼓励这一点,horizontalAnchors
和 edgeAnchors
使用 leadingAnchor
和 trailingAnchor
布局锚点。
当约束 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
布局优先级是一个具有以下值的枚举
.required
- UILayoutPriorityRequired
(默认).high
- UILayoutPriorityDefaultHigh
.low
- UILayoutPriorityDefaultLow
.fittingSize
- UILayoutPriorityFittingSizeLevel
要存储由 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
。
Anchorage 将表达式左侧的 translatesAutoresizingMaskIntoConstraints
属性设置为 false
,因此你永远不需要手动设置此属性。 请务必注意这一点,以防容器视图依赖于设置为 true
的 translatesAutoresizingMaskIntoConstraints
。 我们倾向于将子视图放在表达式的左侧,以避免这个问题,尤其是在约束到系统提供的视图时。
Anchorage 重载了一些 Swift 运算符,这可能会导致编译时间增加。 你可以通过用 /
包围这些运算符来减少这种开销,如下所示
运算符 | 更快的替代方案 |
---|---|
== |
/==/ |
<= |
/<=/ |
>= |
/>=/ |
例如,view1.edgeAnchors == view2.edgeAnchors
将变为 view1.edgeAnchors /==/ view2.edgeAnchors
。
要使用 CocoaPods 将 Anchorage 集成到你的 Xcode 项目中,请在你的 Podfile 中指定它
pod 'Anchorage'
要使用 Carthage 将 Anchorage 集成到你的 Xcode 项目中,请在你的 Cartfile 中指定它
github "Rightpoint/Anchorage"
运行 carthage update
以构建框架,并将构建的 Anchorage.framework
拖到你的 Xcode 项目中。
此代码和工具采用 MIT 许可证。 请参阅此存储库中的 LICENSE
文件。
欢迎任何想法和贡献!