使用 Cartography,您可以使用声明式代码设置 Auto Layout 约束,而无需任何字符串类型的输入!
简而言之,它允许您将此代码替换为
addConstraint(NSLayoutConstraint(
item: button1,
attribute: .Right,
relatedBy: .Equal,
toItem: button2,
attribute: .Left,
multiplier: 1.0,
constant: -12.0
))
如下代码
constrain(button1, button2) { button1, button2 in
button1.right == button2.left - 12
}
如果您最终在生产环境中使用 Cartography,我很乐意听到您的反馈。您可以通过 Twitter 或 电子邮件 联系我。
要使用 CocoaPods 将 Cartography 集成到您的 Xcode 项目中,请在您的 Podfile
中指定它
target '<Your Target Name>' do
pod 'Cartography', '~> 3.0'
end
然后,运行以下命令
$ pod install
使用您的 UIView
或 NSView
实例以及一个闭包调用 constrain
* 函数,在闭包中声明视图不同属性之间的约束
constrain(view1, view2) { view1, view2 in
view1.width == (view1.superview!.width - 50) * 0.5
view2.width == view1.width - 50
view1.height == 40
view2.height == view1.height
view1.centerX == view1.superview!.centerX
view2.centerX == view1.centerX
view1.top >= view1.superview!.top + 20
view2.top == view1.bottom + 20
}
对于等式或不等式运算符左侧的每个视图,Cartography 将自动将其 translatesAutoresizingMaskIntoConstraints
属性设置为 false
。
如果视图不受您控制 - 例如,如果它属于 Apple 提供的 UIViewController
类 - 您在声明其约束时应格外小心。
您可以将多个约束捕获在一个组中,然后在稍后用新约束替换它们。
constrain(view) { view in
view.width == 100
view.height == 100
}
let group = ConstraintGroup()
// Attach `view` to the top left corner of its superview
constrain(view, replace: group) { view in
view.top == view.superview!.top
view.left == view.superview!.left
}
/* Later */
// Move the view to the bottom right corner of its superview
constrain(view, replace: group) { view in
view.bottom == view.superview!.bottom
view.right == view.superview!.right
}
UIView.animate(withDuration: 0.5, animations: view.layoutIfNeeded)
为了方便起见,constrain
函数还会返回 ConstraintGroup
实例
let group = constrain(button) { button in
button.width == 100
button.height == 400
}
Cartography 支持截至 iOS 8 和 OS X 10.9 的所有内置属性,包括:
width
height
top
right
bottom
left
leading
trailing
centerX
centerY
baseline
以及 iOS 特有的
firstBaseline
leftMargin
rightMargin
topMargin
bottomMargin
leadingMargin
trailingMargin
centerXWithinMargins
centerYWithinMargins
edgesWithinMargins
这些属性可以使用以下运算符进一步细化:*
、/
、+
和 -
。
此外,它还支持方便的复合属性,允许您一次分配多个属性
constrain(view) { view in
view.size == view.superview!.size / 2
view.center == view.superview!.center
}
constrain(view) { view in
view.edges == inset(view.superview!.edges, 20, 20, 40, 20)
}
如果您需要通过公共边缘对齐多个视图,可以使用 align
函数
constrain(view1, view2, view3) { view1, view2, view3 in
align(top: view1, view2, view3)
}
这等效于 view1.top == view2.top; view2.top == view3.top
。top
、right
、bottom
、left
、leading
、trailing
、centerX
、centerY
和 baseline
也存在类似的变体。
对于水平或垂直分布多个视图,您可以使用 distribute
函数
constrain(view1, view2, view3) { view1, view2, view3 in
distribute(by: 10, horizontally: view1, view2, view3)
}
这等效于 view1.trailing == view2.leading - 10; view2.trailing == view3.leading - 10
。
您可以使用 ~
运算符设置约束的优先级
constrain(view) { view in
view.width >= 200 ~ UILayoutPriority(100)
view.height >= 200 ~ .required
}
由于 ==
、>=
、<=
和 ~
发出 NSLayoutConstraint
实例,如果您需要在稍后引用布局约束,则可以捕获它们的结果
var width: NSLayoutConstraint?
constrain(view) { view in
width = (view.width == 200 ~ 100)
}
请注意,声明复合属性会一次返回多个约束
var constraints: [NSLayoutConstraint]?
constrain(view) { view in
constraints = (view.size == view.superview!.size ~ .defaultLow)
}
在此处阅读文档 here。有关更多信息,请参阅 gh-pages 分支。
* 由于 Xcode 11 和 swift 5.1,关键字 constrain
与 CommonUISDK 使用的关键字冲突... 因此,必须使用模块名称调用该函数才能使其正常工作
例如:Cartography.constrain
如果您在 Xcode 10.3 或更早版本中使用它,您仍然可以按原样使用它,而无需在函数旁边使用模块名称。
对于 Swift 3.x:版本 <= 1.1.0
对于 Swift 4.x:版本 >= 2.0.0
对于 Swift 5.x:版本 >= 4.0.0
如果您有任何问题,请随时 提交 issue。
Cartography 由 Robb Böhnke 构建,由 Orta Therox 维护,并受到 FLKAutoLayout (由 Florian Kugler 创建) 的启发。