对于开发者来着,与用户最近的距离就是通过app上的一个个界面,一个好的布局不仅能让开发者适配的工作量减少很多,也会给用户带来比较好的体验。
对于自动布局,最早的就属于Autoresizing Mask,在苹果没有推出AutoLayout之前,适配工作主要就靠Autoresizing Mask去完成,但随着要求的变高,只能约束具有等级关系的两个view,对于左右同等级的视图却达不到很好的控制。iOS6之后,苹果官方推出了AutoLayout,不仅包含了Autoresizing Mask的所有功能,而且对兄弟视图之间的约束有了更完美的控制。
但由于官方的布局写法太过繁琐,可谓又臭又长,可读性也比较不好。因此催生了一些在此基础上封装的第三方的自动布局库,如Masonry,以及本文要讲述的PureAutoLayout。
我们可以清晰的看到,PureAutoLayout不仅支持Objective-c,还支持所有版本的Swift.。这也是他的优势所在。
其他不多说了,简单看一下他的内部结构吧
正如名字一样,内部结构也是一样的“Pure”,作者分别对UIView,NSArray和NSLayoutConstraint进行了拓展。方法名以auto开头,方便Xcode的提示。
一,子视图与父视图之间的约束
autoCenterInSuperview
autoCenterInSuperviewMargins
//处于superview的中心(Margin 是iOS8新增的一个属性,是View的一边与其子View对应的边的推荐最小距离,默认16.)
autoAlignAxisToSuperviewAxis:(ALAxis)axis
autoAlignAxisToSuperviewMarginAxis:(ALAxis)axis
//在superview的某一个轴的中心(ALAxisVertical相对父视图左右等距;ALAxisHorizontal上下等距)
autoPinEdgeToSuperviewEdge:(ALEdge)edge
autoPinEdgeToSuperviewMargin:(ALEdge)edge
//距离superview的 左/右/上/下/ 的距离 默认和superview等bounds。
autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLayoutRelation)relation
//距离父视图某个边距的取值范围
其中:
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1, //小于等于16(Margin)
NSLayoutRelationEqual = 0, //等于16(Margin)
NSLayoutRelationGreaterThanOrEqual = 1,//大于等于16(Margin)
};
autoPinEdgesToSuperviewEdges
// 与父视图的边缘固定(frame和父视图相同) 相当于默认 inset UIEdgeInsetsMake(0, 0, 0, 0)
autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset
//距离superview的 左/右/上/下/ 的距离 inset为设定的距离 默认为 NSLayoutRelationEqual (比如距离superview的左边20)
autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation
//可以自定义 NSLayoutRelation属性 设置距父视图边缘的一个取值范围 (比如距离superview左边大于等于20)
autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets
//可以自定义距离superview四周的距离 如:UIEdgeInsetsMake(10, 10, 10, 10)
autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge
//忽略某个属性 (我只想添加三个属性,又想一个方法写好,那就用这个方法,后面的是拒绝一个边缘的设定,让它不生效。)
二,子视图兄弟间的关系
autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView
//当前视图的上/下/左/右 距离 otherView的 上/下/左/右 的距离 这里默认是都是0
autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset
//当前视图的上/下/左/右 距离 otherView的 上/下/左/右 的距离
autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation
//当前视图的上/下/左/右 距离 otherView的 上/下/左/右 的距离的取值范围
autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView
//当前视图 和 otherView 同轴 默认offset为0
autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withOffset:(CGFloat)offset
//当前视图 和 otherView 同轴 偏移量为offset
autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation
//当前视图 和 otherView 同轴 偏移量为offset 另加取值范围
autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation
//当前视图 和 otherView 同轴 偏移量为offset 另加取值范围
autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView
//当前视图与otherView 同轴 无偏移量
autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView
//当前视图 与 otherView 等宽/登高
autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier
//当前视图 与 otherView 宽or高 倍数比
三,视图本身
autoSetDimensionsToSize:(CGSize)size
//设置视图的宽和高
autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size
//设置视图的宽or高
)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size relation:(NSLayoutRelation)relation
//设置宽or高 的范围
三,视图数组(适用于沿着 x or y 轴排列的视图)
autoAlignViewsToEdge:(ALEdge)edge
//视图根据edge依次排列
autoAlignViewsToAxis:(ALAxis)axis
//视图根据某轴依次排列
autoMatchViewsDimension:(ALDimension)dimension
//视图都设置同一个宽度or高度
autoSetViewsDimension:(ALDimension)dimension toSize:(CGFloat)size
//视图都设置同一个宽度or高度 同时设定值
autoSetViewsDimensionsToSize:(CGSize)size
//视图同宽高
下面的方法是一个方法簇
autoDistributeViewsAlongAxis:(ALAxis)axis alignedTo:(ALAttribute)alignment withFixedSpacing:(CGFloat)spacing ;
autoDistributeViewsAlongAxis:(ALAxis)axis alignedTo:(ALAttribute)alignment withFixedSpacing:(CGFloat)spacing insetSpacing:(BOOL)shouldSpaceInsets;
autoDistributeViewsAlongAxis:(ALAxis)axis alignedTo:(ALAttribute)alignment withFixedSpacing:(CGFloat)spacing insetSpacing:(BOOL)shouldSpaceInsets matchedSizes:(BOOL)shouldMatchSizes
/*
axis:某轴
alignment:排列方向
spacing:间距
shouldSpaceInsets:第一个视图与父视图是否有间距
shouldMatchSizes: 视图是否有相同的size
*/
上面的大部分的方法了,真正理解还是要自己试了才知道。另外需要注意的就是约束冲突的问题,在iOS8之前的系统会出现崩溃的现象。添加约束的时候,检查约束是否冲突的要素是思考:一个视图加上约束,能不能固定它或者说能不能限制它的frame。