DLLLayout
Introduce
DLLLayout 是一个基于 UIView.frame 的轻量级 iOS 布局框架。相比苹果的 AutoLayout,它有着更友善的 API 和更高的性能,虽然功能上不如 AutoLayout 大又全,比如不支持 greaterThan、lesserThan、priority 等,但也能够满足90%以上的业务场景。在性能上,如果需要通过视图内容自适应宽高(例如 UILabel、UIButton 根据内容计算宽高),布局耗时为苹果 AutoLayout 的 1/2 左右;反之如果设置了视图的宽高,布局耗时只有苹果 AutoLayout 的不到 1/8,并且能够兼容 UIView.transform。
Theory
给 UIView 设置布局规则,通过 hook UIView.layoutSubviews,在这个方法里对设置过布局规则的视图设置 frame,实现布局功能。因为布局活动触发在系统的 layoutSubviews 之前,所以仍然可以通过重写子类的 layoutSubviews 来实现自己的布局。
Example
克隆仓库后,在Example目录下先运行 pod install
,就可以运行演示工程。
Requirement
iOS 6.0 +
Installation
DLLLayout 可以通过 CocoaPods 获得。 只需要在你的 Podfile 中添加如下代码:
pod "DLLLayout"
Usage
通常来说,一个视图的布局是一个矩形,所以需要能够得到四条边的位置才能够进行布局。但是一些视图,不如 UILabel、UIButton、UIImageView 等等,需要根据它们的内容来自动计算宽高,那么如果我们对这些视图不设置足够的条件,也会根据他们的内容自动计算出布局所用的宽高,不过这样会有一定的性能消耗。如果不能够得到视图四边的位置,则会抛出异常。
在 UIView 实例化之后就可以对它设置布局规则,不需要像 AutoLayout 一样先加入到视图层级中再设置。
UIView *view = [[UIView alloc] init];
// 给 view 设置布局规则
[view dll_setLayout:^(DLLLayout *layout) {
layout.width(100) // 宽度100
.height(50) // 高度50
.centerX(0) // x轴在父视图居中 偏移量0
.topMargin(50); // 相对父视图顶边距50
}];
也可以设置视图的相对依赖关系。注意:只能依赖同一视图层级下的子视图,或者是自己的父、子视图。
UIView *containerView = [[UIView alloc] init];
containerView.backgroundColor = [UIColor redColor];
UIView *leftInnerView = [[UIView alloc] init];
leftInnerView.backgroundColor = [UIColor yellowColor];
UIView *rightInnerView = [[UIView alloc] init];
rightInnerView.backgroundColor = [UIColor blueColor];
[containerView addSubview:leftInnerView];
[containerView addSubview:rightInnerView];
// containerView是父视图,leftInnerView和rightInnerView是两个子视图
// 父视图宽度300,高度100,x和y都居中
[containerView dll_setLayout:^(DLLLayout *layout) {
layout.width(300)
.height(100)
.centerX(0)
.centerY(0);
}];
// leftInnerView的宽度是父视图宽度的0.5倍少15,高度比父视图的高度少20,左边距10,y轴居中
[leftInnerView dll_setLayout:^(DLLLayout *layout) {
layout.relative.width.to(containerView.dll_width.multiple(0.5).offset(-15))
.relative.height.to(containerView.dll_height.offset(-20))
.leftMargin(10)
.centerY(0);
}];
// leftInnerView的宽度是父视图宽度的0.5倍少15,高度比父视图的高度少20,右边距10,y轴居中
[rightInnerView dll_setLayout:^(DLLLayout *layout) {
layout.relative.width.to(containerView.dll_width.multiple(0.5).offset(-15))
.relative.height.to(leftInnerView.dll_height)
.rightMargin(10)
.centerY(0);
}];
在 UIViewAnimation 中,因为要实时更新视图的 frame,所以在使用 DLLLayout 更新布局规则之后,需要手动调用 dll_updateFrame 方法来立即更新 frame。
[UIView animateWithDuration:0.25 animations:^{
[view dll_updateLayout:^(DLLLayout *layout) {
layout.width(300);
}];
// 更新布局规则之后,手动调用dll_updateFrame方法,立即更新frame。
[view dll_updateFrame];
}];
Feature
- 比 Auto Layout 性能更高。
- 支持 Affine Transform。
Author
xiaobinlzy, xiaobinlzy@163.com
License
DLLLayout is available under the MIT license. See the LICENSE file for more info.
Update Log
0.1.1
支持 UIView.transform。