前言
UI
布局对于iOS
开发者来说并不陌生,在iOS6
之前,大家都是通过UI
控件的Frame
属性和Autoresizing Mask
来进行UI
布局的(简称为手动布局)。AutoLayout
则是苹果公司在iOS6
推出的一种基于约束的,描述性的布局系统(简称为自动布局),这里主要从四个方面来阐述iOS布局及实践。
- 手动布局和自动布局
AutoLayout
原理AutoLayout
的性能Masnory
的使用
首先对手动布局和自动布局做一个简单的介绍:
手动布局和自动布局
- 手动布局:指的是通过直接修改视图的
frame
属性的方式对界面进行布局。
对于
IOS
的app
开发者来说,不会像Android
开发者一样为很多的屏幕尺寸来做界面适配,因此手动调整frame
的方式来布局也能工作良好。但是还是会有一些问题,如设备发生旋转、适配ipad
等,并且保证视图原来之间的相对关系,则以上的方法都是无法解决的。如果要做这些适配,在AutoLayout
未出来之前需要编写大量的代码,并且花费大量的调试适配时间。
- 自动布局:指的是使用
AutoLayout
的方式对界面进行布局。
AutoLayout
是苹果本身提倡的技术,在大部分情况下也能很好的提升开发效率,但是AutoLayout
对于复杂视图来说常常会产生严重的性能问题。随着视图数量的增长,AutoLayout
带来的CPU
消耗会呈指数级上升。 如果对界面流畅度要求较高(如微博界面),可以通过提前计算好布局,在需要时一次性调整好对应属性 ,或者使用ComponentKit
、AsyncDisplayKit
等框架来处理界面布局。
下面,我们来分析下 AutoLayout的原理。
AutoLayout的原理
这里通过使用Masonry
来进行布局,从而来分析AutoLayout
的原理,先简要了解下Masonry
。
Masonry
是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了,并具有高可读性,而且同时支持 iOS
和 Max OS X
。
Masnory
支持的常用属性如下:
@property (nonatomic, strong, readonly) MASConstraint *left; //左侧
@property (nonatomic, strong, readonly) MASConstraint *top; //上侧
@property (nonatomic, strong, readonly) MASConstraint *right; //右侧
@property (nonatomic, strong, readonly) MASConstraint *bottom; //下侧
@property (nonatomic, strong, readonly) MASConstraint *leading; //首部
@property (nonatomic, strong, readonly) MASConstraint *trailing; //首部
@property (nonatomic, strong, readonly) MASConstraint *width; //宽
@property (nonatomic, strong, readonly) MASConstraint *height; //高
@property (nonatomic, strong, readonly) MASConstraint *centerX; //横向中点
@property (nonatomic, strong, readonly) MASConstraint *centerY; //纵向中点
@property (nonatomic, strong, readonly) MASConstraint *baseline; //文本基线
其中leading
与left
,trailing
与right
在正常情况下是等价的,但是当一些布局是从右至左时(比如阿拉伯语) 则会对调。
同时,在Masonry
中能够添加AutoLayout
约束有三个函数:
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;//只负责新增约束` AutoLayout`不能同时存在两条针对于同一对象的约束,否则会报错
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;//针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;//则会清除之前的所有约束 仅保留最新的约束
我们在代码中,经常会使用到eq