BxLayout
BxLayout为在代码中执行iOS自动布局提供了一个漂亮的界面。
用法
入门
假设您有一个文本框 textField
和一个标签 label
,它们是一个视图 view
的子视图。
- 您希望将文本框放置在视图中央,并且它应该覆盖到边缘。
- 您希望将标签放在文本框下方,间距为5点。
- 您希望将文本框的左边与标签的左边对齐。
根据上述思路,代码可以直接衍生出
view.addSubviews(textField, label) // Adds the views to the view, no need to do so otherwise
.layout { superview, textField, label in
// You need to declare all views that you want to layout
// * The first parameter is always the superview onto which views are added
// * Subsequent parameters are in the order of the parameters passed into the function
// The declared views are not views anymore but layout objects.
textField.center.y == superview.center.y
textField.leading == superview.margin.leading
textField.trailing == superview.margin.trailing
label.top == textField.bottom + 5
label.leading == textField.leading
}.apply()
// `apply` actually creates the layout constraints and sets the autoresizing masks of
// all subviews to `false`.
便捷函数
上述代码已经看起来非常简洁,然而,还有两个函数可以使得布局代码更加美观
follow
:布局对象上描述了一组等式约束的函数。stack
:将视图并排布局的函数。使用这些函数,以上代码可以重写如下
view.addSubviews(textField, label)
.layout { superview, textField, label in
textField.follow(superview, on: [.centerY, .marginLeading, .marginTrailing])
stack(textField, 5, label)
label.leading == textField.leading
}.apply()
默认情况下,stack函数垂直堆叠视图,但是可以显式地指定方向
stack(textField, 5, label,
orientation: .vertical)
高级便捷功能
上面的便捷函数更加强大。
函数follow
的非正式定义如下
func follow(<view>, on: <set of equalities>, insetBy: <edge insets>)
等式的集合的可能值是直观的,还有一些组合。以上对follow
的应用可以重写如下
textField.follow(superview, on: [.centerY, .marginHorizontal])
默认等式的集合设置为所有边。
边偏移给出为EdgeInsets(leading:trailing:top:bottom:)
,可以使用任何参数组合。默认情况下,所有边都为零。
stack函数可以接受任何数量的参数。参数序列必须遵守以下约束
- 视图必须跟在另一个视图或数字之后(没有数字表示数字为0)。
- 数字必须跟在视图之后。
- superview只能是第一个和/或最后一个参数,且必须有至少一个视图介于两者之间。如果参数序列不符合以上要求,应用stack函数可能会导致runtime error。
更多高级概念
到目前为止,我们主要考虑了等式。然而,布局约束可以做更多的事情。BxLayout可以轻松实现布局约束提供的所有功能。
- 不等式:例如,
view1.height <= view2.height
- 常数的添加:例如,
view1.height == view2.height + 10
- 与系数相乘:例如,
view1.height == view2.height * 2
- 以上组合:例如,
view1.height <= view2.height * 2 + 10
- 优先级(其中优先级是
UILayoutPriority
类型):例如,view1.height == view2.height ~ .priorityLow
- 赋值(如果以后需要显式地使用布局约束):例如,
view1.height == view2.height => self.myLayoutConstraint
(《myLayoutConstraint》应为NSLayoutConstraint?
类型)
最终,复杂的布局可能需要多个superview之间的约束。然而,上述接口仅在添加子视图时可用,因为需要布局对象。因此,还有一个可以用来获取布局对象的功能。应用方法完全相同。
view.with(subviewOfOtherView1, subviewOfOtherView2)
.layout { superview, view1, view2 in
// perform layout
}.apply()
CocoaPods
BxLayout可以通过CocoaPods轻松使用。只需将以下之一添加到您的Podfile中:
pod 'BxLayout'
pod 'Bx/Layout'
许可协议
BxLayout的使用受Apache 2.0许可证约束。