使用 Cartography,您可以在声明性代码中设置布局约束,而无需任何字符串!
简而言之,它允许您替换此内容
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 或 电子邮件联系我。
调用 constrain
函数,并将您的 UIView
或 NSView
实例以及一个闭包作为参数,在闭包中声明你的视图之间不同属性之间的约束
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
。
如果视图不是由您控制的 - 例如 如果它属于苹果提供的 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.animateWithDuration(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 以及之后版本的内置所有属性,这些是:
宽度
高度
顶
右
底
左
leading
trailing
horizontalCenterX
verticalCenterY
baseLine
以及 iOS 独有的
firstBaseLine
左边距
右边距
上边距
底边距
leadingMargin
trailingMargin
horizontalCenterWithinMargins
verticalCenterWithinMargins
marginsEdges
这些可以用以下运算符进一步细化: *
,/
,+
和 -
。
此外,它还支持方便的复合属性,允许您一次分配多个属性。
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 ~ 100
view.height >= 200 ~ 100
}
由于 ==
、>=
、<=
和 ~
会产生 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 ~ 100)
}
请在此处阅读文档 [链接]。更多信息,请参阅 gh-pages 分支。
如果您有任何疑问,请不要犹豫,提交一个问题。
Cartography 由 Robb Böhnke 构建,并受到佛罗里安·库格勒(Florian Kugler)的杰出作品 FLKAutoLayout 的启发。