源地址:https://github.com/robb/Cartography
使用Cartography,你可以抛开链式语法,使用声明式的代码设置你的自动布局约束!
简而言之,他可以让你将如下的代码:
addConstraint(NSLayoutConstraint(
item: button1,
attribute: .Right,
relatedBy: .Equal,
toItem: button2,
attribute: .Left,
multiplier: 1.0,
constant: -12.0
))
替换为以下的代码
layout(button1,button2){ button1,button2 in
button1.right == button2.left - 12
如果你在使用Cartography的过程中遇到困难, 可以联系作者 [Twitter] 或者 [email] .
用法
调用layout
方法,传入UIView
或NSView
类型实例,在闭包中声明各个视图的不同属性之间的约束:
layout(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
}
对于每个等式或不等式左边的view,Cartography会自动将其translatesAutoresizingMaskIntoConstraints
属性设置为false
。如果这个view不是受你控制的—-比如它是属于一个苹果提供的UIViewController
类—-你需要在声明约束时对其保持适当的关注。
要注意的是,layout
在必要的情况下会对自动对视图进行重新布局。如果你想要自己控制这个布局的步骤的话,你可以用constrain
方法来代替它:
constrain(view1) { view1 in
view1.width == 100
view1.height == 100
view1.center == view.superview!.center
}
UIView.animateWithDuration(0.5, animations: view1.layoutIfNeeded)
约束的替换
你可以获取一个约束组(group)内的多种约束,随后用新的一些约束来替换它们。
constrain(view) { view in
view.width == 100
view.height == 100
}
// 获取约束组
let group = ConstraintGroup()
// 使'view'关联到它的父视图的左上角
constrain(view, replace: group) { view in
view.top == view.superview!.top
view.left == view.superview!.left
}
/* 之后 */
// 将这个view移动到它的父视图的右下角
constrain(view, replace: group) { view in
view.bottom == view.superview!.bottom
view.right == view.superview!.right
}
UIView.animateWithDuration(0.5, animations: view.layoutIfNeeded)
为了方便起见,layout
和constrain
方法都会返回ConstraintGroup
实例:
let group = layout(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
这些属性都可以通过以下运算符来进一步细化:*
, /
, +
and-
。
此外,它提供了一种方便的方法,支持复合属性的设置,因此你可以一次分配多个属性。
layout(view) { view in
view.size == view.superview!.size / 2
view.center == view.superview!.center
}
layout(view) { view in
view.edges == inset(view.superview!.edges, 20, 20, 40, 20)
}
多个视图对齐
如果你需要让多个视图对齐一个共有的边缘,你可以使用align
方法。
layout(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
函数:
layout(view1, view2, view3) { view1, view2, view3 in
distribute(by: 10, horizontally: view1, view2, view3)
}
这相当于 view1.trailing == view2.leading - 10; view2.trailing == view3.leading - 10
.
设置优先级
你可以通过~
操作符来设置约束的优先级:
layout(view) { view in
view.width >= 200 ~ 100
view.height >= 200 ~ 100
}
获取约束
由于==
, >=
, <=
和 ~
生成了 NSLayoutConstraint
实例, 如果你在之后需要用到生成的结果的话,你可以用如下的方法来获取它:
var width: NSLayoutConstraint?
layout(view) { view in
width = (view.width == 200 ~ 100)
}
要注意的是,复合属性的声明一次返回多个约束:
var constraints: [NSLayoutConstraint]?
layout(view) { view in
constraints = (view.size == view.superview!.size ~ 100)
}
文档
在这里可以查看文档。 更多的信息可以在gh-pages 查看。
支持
如果你有疑问的话,别犹豫,直接提交。
关于Cartography
Cartography由Robb Böhnke创建并受Florian Kugler的[FLKAutoLayout]项目启发。