又,的确是又一个. 因为目前已经不少为简化 AutoLayout 约束书写而生的库了.
我写这个库的时候,主要是受 PureLayout,SnapKit 及我之前尝试解决这个问题的另一个轮子 - PinAutoLayout 影响.
基于 PinAuto 布局的代码看起来像下面这样
self.view.addSubview(box)
box.pa_width.eq(100).install()
box.pa_height.eq(100).install()
box.pa_centerX.install()
box.pa_centerY.install()
背景
虽然 PinAutoLayout 可解决我 90% 的手写 AutoLayout 约束的问题,但是之前的写法灵活性太差. 所以前几天,在我稍微空闲的晚上,就开始重新构思 PinAuto 这个库了.按理说 SnapKit 应该是大部分 Swift 开发都的选择,然后我还是想尝试自己造下轮子,因为我也有自己的想法考虑和实践经验考虑在里面.
它有什么特点
相比于 SnapKit ,PinAuto 可以说更简单, 因为 SnapKit 以 DSL 自称,我却只是提供合适的简写及链式写法.
- 一次只生成一条约束
- 提供链式写法,不需要 block 及 closure
- 约定优于配置,默认情况下,It Just Works
一次只实现一条约束,简化的写法,对于代码的可读性也是有好处的.
对于不使用 block 或者 closure 有一个最大的好处就是整个编写约束的过程都可以是链式调用.
不过一个不足的地方就是最后都需要调用 install 来最后生成和添加约束.
不过我已经在每一个方法上添加了 @warn_unused_result 所以如果你忘记了调用 install 的话,
一般是会有警告的.
使用详解
这个详解,也算是我对 AutoLayout 约束布局的一个简单的总结.
布局时我们到底在布什么局?
布局体现在约束中,而约束,我认为主要有如下三种:
1. 对自己的约束,如宽,高,长宽比.
2. 对自己在父容器中位置,大小等约束
3. 对自己及兄弟节点位置及大小关系的约束.
下面在上面的三种使用进行示例说明:
所以的约束都需要手动 install 下面的示例中,我会省略 install,实际使用中,没有如果调用 install 大部分情况会有警告.
约束自己
- 宽度约束
view.pa_width.eq(100) - 高度约束
view.pa_height.eq(80) - 宽高比
view.pa_aspectRatio(0.5)这个约束表示: 高是宽的一半
约束自己在父容器中的位置.
如果 会 CSS 的不防与 CSS 中的 margin 属性对应
- 距离父容器左边约束
view.pa_leading.eq(15) - 距离父容器右边的约束
view.pa_trailing.eq(15) - 距离父容器顶部的约束
view.pa_top.eq(30) - 距离父容器底部的约束
view.pa_bottom.eq(30)还有其他比较少用的pa_left,pa_right等属性.
居中:
- 跟父容器水平居中 view.pa_centerX
- 跟父容器垂直居中 view.pa_centerY
约束自己跟兄弟 View 节点的位置.
- 在兄弟节点的右边
view.pa_after(viewA) - 在兄弟节点的左边
view.pa_before(viewA) - 在兄弟节点的下面
view.pa_below(viewA) - 在兄弟节点的上面
view.pa_above(viewA) - 跟兄弟节点左对齐
view.pa_leading.equalTo(viewA) - 跟兄弟节点右对齐
view.pa_trailing.equalTo(viewA)
其他属性,类似写法,这里不一一举例了.
不得不说的时,关于兄弟节点的布局,我主要受 Android 的 RelativeLayout 影响比较大.
值,关系,优先级
值 与 关系
对于值的设置,提供了
- eq 等于, equal,equalTo 也可以,如果你愿意的话.
- lte 小于等于 ,也可以用 lessThanOrEqual
- gte 大于等于, 也可以用 greaterThanOrEqual
为了使设置值的时候的语义更起来更好,提供了 offset 方法.
如为了表示 ViewA 在 ViewB 的右边,两者间距 30 点.
可以这样写 :viewA.pa_after(viewB).offset(30)
也可以在设置值之后再指定关系, 使用 withRelation(.GreaterThanOrEqual)
优先级
默认的优先级是 Required,
- 指定为较高的优先级 withHighPriority
- 指定使用较低的优先级 withLowPriority
- 指定具体的优先级 withPriority(300)
今天先介绍到这里, 后面我再介绍我的 UI 布局速写脚本.
希望得到大家的意见和建议.