AutoLayout的起源、概念和基本知识

随着iOS的设备的尺寸的拓展、还有iphone 和 ipad 一个app的模式的流行、传统的fram 布局(即指定 x y width height)已经很难做到非常好的效果、所以关系形布局 Autolayout开始大展身手、受到越来越多开发者的青睐。

Autolayout的目标和多种布局的比较

目标

苹果在官方的文档中,是这么形容autolayout的目标的“苹果设计autolayout主要是帮助开发者、应对越来越多的变化、 包括外部变化和内容变化”。
外部变化主要包括:

  • ipad 分屏
  • 不同的iphone尺寸
  • 使用时出现电话等call bar

内容变化包括:

  • 文本内容和图片大小等的变化
  • 支持动态字体、用户可以设定不同大小的字体等

在我看来、从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 布局会是这样的:
AutoLayout的起源、概念和基本知识_第1张图片

autoLayout会是这样的:
AutoLayout的起源、概念和基本知识_第2张图片

三种布局方式的比较

目前iOS的布局方式有三种、分别是code frame、autoResize、autoLayout。
code frame是最原始的方法、可以做到非常精确到设定、但是当view非常多、层次非常复杂的时候、重新计算frame会变成非常大的工作量。
autoResizing是苹果之后推出的应对多尺寸屏幕适配的方法、但是有两个缺点

  1. 只能调整父view 和子view的关系、而不能调整两个子view的关系
  2. 只能应对外部变化、即父view的大小变化、而不能应对内容变化

而autolayout能够应对code frame 和 autoResizing所不能做到的功能、有以下优点:

  1. 同时应对外部变化和内部变化
  2. 更符合我们的思路、因为它是是描述性的、不关心具体的frame、只关心ui之间的关系、所以我们只要按照布局时的思路来写就可以了、系统会自动计算最终的布局
  3. 向后兼容和之前的frame布局可以同时存在、使用的成本就大大减小了
  4. 大大减少了布局的工作量、尤其是当布局大量变化的时候

约束 constraint

我们知道、autolayout就是由view之间的约束组成、那么什么是约束呢?
约束是描述两个view之间关系的语句、它的重点就是、两个view之间有哪些联系和影响、使用下面的列子说明:

AutoLayout的起源、概念和基本知识_第3张图片

名称 内容
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 、数字越大、约束的级别越高
系统还定义了枚举类型的约束优先级可以使用

使用autoLayout 要注意的地方

充分性:

即必须有充分的条件让系统去布局 一个充分的布局在每个坐标轴上至少要有两个几何规则、总共4个、从而保证条件是充分的

没有充足的约束、或者约束之间是不一致的、很容易导致视图的丢失、查看是否充分、可以使用hasAmbiousLaout 函数、如果是约束冲突、log里面会提供、暂时没有更好的方法
另外如果想debug的话、可以在预期视图出现之后、例如:viewWillAppear 和 awarkFromNib打断点

约束的优先级

from 1 to 1000 、数字越大、约束的级别越高
系统还定义了枚举类型的约束优先级可以使用

autolayout的特点

内在内容大小

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、使用比较方便、而且不太用担心停止更新的情况(即使停止更新、也是使用的原生布局、是向后兼容的、最多一些新的方法不能使用、但不会出问题)

你可能感兴趣的:(iOS)