随着iOS的设备的尺寸的拓展、还有iphone 和 ipad 一个app的模式的流行、传统的fram 布局(即指定 x y width height)已经很难做到非常好的效果、所以关系形布局 Autolayout开始大展身手、受到越来越多开发者的青睐。
苹果在官方的文档中,是这么形容autolayout的目标的“苹果设计autolayout主要是帮助开发者、应对越来越多的变化、 包括外部变化和内容变化”。
外部变化主要包括:
内容变化包括:
在我看来、从frame布局到autoLayout布局、是两种思路的转化、完全不同的思路。如苹果所说
Auto Layout represents an entirely new paradigm. Instead of thinking about a view’s frame, you think about its relationships.
就好像我让一个小孩去买菜、frame的思路会是:往前走500米、然后左拐、然后直走300米、然后左转走100米就到了。 而autolayout的思路是:往前走、看到一个银行、然后右转直走看到一个超市、然后左转一直走到菜市场。从人的思维来讲、其他autolayout更符合人脑思考的方式、但是很多人因为一直使用frame、所以会很不习惯autolayout、但我觉得、关系型的布局会是大势所趋、当你习惯之后、会觉得以前的frame布局、简直太难用啦。
frame 布局会是这样的:
目前iOS的布局方式有三种、分别是code frame、autoResize、autoLayout。
code frame是最原始的方法、可以做到非常精确到设定、但是当view非常多、层次非常复杂的时候、重新计算frame会变成非常大的工作量。
autoResizing是苹果之后推出的应对多尺寸屏幕适配的方法、但是有两个缺点
而autolayout能够应对code frame 和 autoResizing所不能做到的功能、有以下优点:
我们知道、autolayout就是由view之间的约束组成、那么什么是约束呢?
约束是描述两个view之间关系的语句、它的重点就是、两个view之间有哪些联系和影响、使用下面的列子说明:
名称 | 内容 |
---|---|
Item1 | 你希望设定的item |
Attribute1 | item1的属性 |
Multiplier | 倍数 |
Item2 | 影响item1的item |
Attribute2 | item2的属性 |
constant | 常量 |
RelationShip | 关系 、包括 >、 =、 < |
所有的约束、其实都是可以等价上述的等式、其中我们需要了解的变量是Attribute和RelationShip、就是我们有哪些属性可以设定、他们有哪几种关系。
虽然约束感觉上很多、但其实看来看去、只是以下约束的组合。
类型 | 说明 | 值 |
---|---|---|
属性 | 左、右、上、下 | NSLayoutAttributeLeft等 |
属性 | 前、后 | NSLayoutAttributeLeading(阿拉伯语等使用) |
属性 | 宽、高 | NSLayoutAttributeWidth |
属性 | centerX、centerY | NSlayoutAttributeCenterX |
属性 | 基线底图放文字的地方 | NSLayoutAttributeBaseLine |
属性 | 占位符 | NSLayoutAttributeNotAnAttribute |
关系 | = > < | NSLayoutRelationLessThan |
from 1 to 1000 、数字越大、约束的级别越高
系统还定义了枚举类型的约束优先级可以使用
即必须有充分的条件让系统去布局 一个充分的布局在每个坐标轴上至少要有两个几何规则、总共4个、从而保证条件是充分的
没有充足的约束、或者约束之间是不一致的、很容易导致视图的丢失、查看是否充分、可以使用hasAmbiousLaout 函数、如果是约束冲突、log里面会提供、暂时没有更好的方法
另外如果想debug的话、可以在预期视图出现之后、例如:viewWillAppear 和 awarkFromNib打断点
from 1 to 1000 、数字越大、约束的级别越高
系统还定义了枚举类型的约束优先级可以使用
view等根据内容的大小、自动适应
压缩阻力是指、当内容和其他的条件冲突时、抗压缩的力度、通过size inspector 设置
内容吸附是指、框架和内容的自然大小的匹配程度、吸附值高、则视图和呈现的内容大小越接近
安装:addConstraint
删除:removeFromSuperView 或者 removeContraints
注意、使用removeContraints不能使用两个等价的约束、而要使用约束的指针、比如
[self addContraint: [Constraint constrintWithItem:***] ]
添加一个新的约束
使用self removeContraint: [Constraint constrintWithItem:***]
即使两个的条件一模一样、也不是同一个约束
可以使用变量的方式保存
如a = [Constraint constrintWithItem:***] [self addContraint: a]
然后使用[self removeContraint:a]
来删除
或者比较两个约束、然后删除在数学上和传递的参数匹配的约束
所有的约束都满足一下的关系式
视图1.属性(关系) 视图1.属性(关系) * 乘数 + 常数
视图将约束作为对象读取、如果两个约束在内存的不同位置、那么即使他们的内容完全相同、系统也会认为他们是不同的约束、这时如果想删除、就可以使用比较功能来实现
目前我们公司使用的pureLayout、基于原生的布局系统的category、使用比较方便、而且不太用担心停止更新的情况(即使停止更新、也是使用的原生布局、是向后兼容的、最多一些新的方法不能使用、但不会出问题)