中文 Why - djs66256/DDFlexbox GitHub Wiki
布局一直是页面开发中比较麻烦和耗时的工作,所以选择一种适合的布局方案就可以明显的提高开发效率。
目前比较常见的布局方案大致分为以下几种:
- 手动布局
- AutoLayout
- Flexbox
其中Flexbox
是前端的布局方案,具体原理这里不再阐述,大家可以参考css标准。在实际的开发与应用中发现,Flexbox
非常契合我们大部分业务场景,特别是以复杂元素展示型为主的场景,比如微博动态流,朋友圈,各种卡片类型等等。那么这里简单对比一下各个布局的优劣。
手动布局 | AutoLayout | Flexbox | |
---|---|---|---|
上手难度 | 低 | 中 | 高 |
复杂性 | 低 | 高 | 中 |
代码量 | 高 | 中 | 低 |
bug率 | 高 | 中 | 低 |
性能 | 高 | 低 | 中 |
动态场景复杂性 | 低 | 高 | 低 |
举个最简单的例子,左右两个view,分别充满父容器的场景。这里就不讨论手动布局的问题了。
+-----------+----------+
| imageView | textView |
+-----------+----------+
如果我们使用 AutoLayout,那么我们必须定义所有边的约束,并且部分约束一定不能定义错误,比如 imageView 的top.lessThanOrEqualToSuperview()
,而不是top.equalToSuperview()
。
imageView.snp.makeConstraints { (m) in
m.left.equalToSuperview().inset(10)
m.top.lessThanOrEqualToSuperview().inset(10)
m.bottom.greaterThanOrEqualToSuperview().inset(10)
m.width.equalTo(40)
m.height.equalTo(40)
}
textView.snp.makeConstraints { (m) in
m.left.equalTo(imageView.snp.right).offset(10)
m.right.top.bottom.equalToSuperview().inset(10)
}
而我们使用 Flexbox 时,我们可以不用考虑这种边界情况,只需要定义元素自身的一些属性即可。
flexbox.row.padding(10).setup { (b) in
b.bindView(imageView).width(40).height(40).marginRight(10)
b.bindView(textView).flexGrow(1).flexShrink(1)
}
上面仅仅是一个最简单的例子,并不能展示出 Flexbox 所有的优势,剩下的就交给大家自己发掘吧。
那么 Flexbox 有没有缺点呢?
答案当然是有的。
Flexbox 采用的是块状元素方案,所以为了达到某些布局样式,则必须定义很多层级的块元素,而这些块元素是展示无关的,所以YogaKit
会带来一个比较严重的 view tree 过深的问题,创建了大量无用的 view。针对这一点,DDFlexbox 从方案角度解决了这个问题,DDFlexbox 是基于 node tree 进行布局,而不是 view tree,简而言之,所有块元素不会强制绑定 view 了。
同时,Flexbox 是块元素的定义,所以对于一些非块元素的场景,就显得有些啰嗦了,但实际经验看来,这种场景并不多。