什么是Auto Layout
Auto Layout,是苹果公司提供的一个基于约束布局,动态计算大小和位置的库,而且已经集成到了Xcode开发环境里里。ide
在引入Auto Layout以前,都是采用手动布局的方式。手动布局的方式原始落后,界面开发维护效率低,为了提升更好得界面引擎给开发这体验,随之引入Auto Layout。工具
来历
Cassowary是个解析工具包,可以有效解析线性等式系统和线性不等式系统,用户的界面中老是会出现不等关系和相等关系,Cassowary开发了一种规则系统能够经过约束来描述视图间关系。约束就是规则,可以表示出一个视图相对于另外一个视图的位置。oop
Auto Layout生命周期
Auto Layout 用一整套布局引擎管理布局的建立,更新,销毁。这一整套布局引擎系统叫作Layout Engine,是Auto Layout的核心,主导着整个布局页面。布局
每一个视图在获得本身的布局以前,Layout engine会将视图,约束,优先级,固定大小计算经过转换成最终的大小和位置。在Layout engine里,会有约束变化到Deferred Layout Pass 再到应用Runloop 在回到约束变化这样的循环机制。以下图所示:flex
约束变化
触发约束变化包括:code
Activating 或 Deactivating
设置constant 或 priority
添加和删除时图
这个Engine遇到约束变化会从新计算layout,获取新值后会call它的superview.setNeedslayout()orm
Deferred Layuot Pass
在这个时候主要是作些容错处理,更新约束有些没有肯定或者缺失布局声明的视图会在这里处理。接着从上而下调用layoutSubviews()来肯定视图各个子视图的位置,这个过程实际上就是将subview的frame从layout engine里拷贝出来。这里要注意重写layoutSubviews()或者执行相似layoutIfNeeded这样可能会马上唤起layoutSubviews()的方法,若是要这样作须要注意手动处理的这个地方本身的子视图布局的树状关系是否合理。cdn
生命周期中须要注意的事项
不要指望frame会马上变化
在重写layoutSubviews()时须要很是当心
使用API约束
[NSLayoutContraint constraintWithItem:view1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-5]
blog
使用VFL语言约束
[NSLayoutConstraint constraintWithVisualFormat:@“[view1]-[view2]" options:0 metrics:nil views:viewsDictionary;
生命周期
VFL几个例子
[view1(50)]-10-[view2(100)] 表示view1宽50,view2宽100,间隔10
[view1(>=50@750)] 表示view1宽度大于50,约束条件优先级为750(优先级越大优先执行该约束,最大1000)
V:[view1][view2(==view1)] 表示按照竖直排,上面是view1下面是一个和它同样大的view2
H:|-[view1]-[view2]-[view3(>=20)]-| 表示按照水平排列,|表示父视图,各个视图之间按照默认宽度来排列
VFL的语法
标准间隔:[button]-[textField]
宽约束: [button(>=50)]
与父视图的关系: |-50-[purpleBox]-50-|
垂直布局: V:[topField]-10-[bottomField]
Flush Views:[maroonView][buleView]
权重:[button(100@20)]
等宽:[button(==button2)]
Multiple Predicates: [flexibleButton(>=70,<=100)]
注意事项
H:和V:每次都是使用一个
视图变量名出如今方括号中,例如[view]
字符串中顺序是按照从顶到底。从左到右
视图间隔以数字常量出现,例如-20-
|表示父视图
使用Auto Layout时须要注意的点
注意禁用 Autoresizing Masks。对于每一个须要使用Auto Layout的视图须要调用setTranslatesAutoresizingMaskIntoConstraints:NO
布局原理是由外向里布局,最早屏幕尺寸,在一层一层往里布局各个元素的大小
删除视图时直接使用removeConstraint和removeConstraints时须要注意这样删除是无法删除视图不支持的约束致使view中还包含着那个约束(使用第三方库时须要特别注意下)。解决这个的办法就是添加约束时用一个局部变量保存下,删除时进行比较删掉和先前那个,还有个办法就是设置标记,constraint.identifier = @“What you want to call”。
VFL语句里不能包含空格和>,<这样的约束
布局约束规则
Auto Layout的Debug
Unsatisfiable Layouts 约束冲突,同一时刻约束没法同时知足
Ambiguous Layouts: 约束缺失
Logical Errors: 布局中的逻辑错误
视图约束不合法,每一个约束至少要引用一个视图,删除视图时必定要注意
无公共父视图之间的相互添加约束会出问题
推荐使用的Auto Layout 第三方库
Masonry
Cartography
SDAutoLayout