使用 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 或 电子邮件 联系我。
使用您的 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.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 以来所有内置属性,如下所示
宽度
高度
顶边
右边
底边
左边
引导边
尾随边
中心X
中心Y
基线
以及 iOS 特定的
第一基线
左边距
右边距
上边距
下边距
前边距
后边距
在边距内中心X
在边距内中心Y
在边距内边缘
这些可以用以下运算符进一步细化: *
,/
,+
和 -
。
此外,它支持方便的复合属性,允许您一次分配多个属性
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 的启发。