AutoLayout的起源、概念和基本知识
2016-02-17 14:19
169 查看
随着iOS的设备的尺寸的拓展、还有iphone 和 ipad 一个app的模式的流行、传统的fram 布局(即指定 x y width height)已经很难做到非常好的效果、所以关系形布局 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会是这样的:
code frame是最原始的方法、可以做到非常精确到设定、但是当view非常多、层次非常复杂的时候、重新计算frame会变成非常大的工作量。
autoResizing是苹果之后推出的应对多尺寸屏幕适配的方法、但是有两个缺点
只能调整父view 和子view的关系、而不能调整两个子view的关系
只能应对外部变化、即父view的大小变化、而不能应对内容变化
而autolayout能够应对code frame 和 autoResizing所不能做到的功能、有以下优点:
同时应对外部变化和内部变化
更符合我们的思路、因为它是是描述性的、不关心具体的frame、只关心ui之间的关系、所以我们只要按照布局时的思路来写就可以了、系统会自动计算最终的布局
向后兼容和之前的frame布局可以同时存在、使用的成本就大大减小了
大大减少了布局的工作量、尤其是当布局大量变化的时候
约束是描述两个view之间关系的语句、它的重点就是、两个view之间有哪些联系和影响、使用下面的列子说明:
所有的约束、其实都是可以等价上述的等式、其中我们需要了解的变量是Attribute和RelationShip、就是我们有哪些属性可以设定、他们有哪几种关系。
系统还定义了枚举类型的约束优先级可以使用
没有充足的约束、或者约束之间是不一致的、很容易导致视图的丢失、查看是否充分、可以使用hasAmbiousLaout 函数、如果是约束冲突、log里面会提供、暂时没有更好的方法
另外如果想debug的话、可以在预期视图出现之后、例如:viewWillAppear 和 awarkFromNib打断点
系统还定义了枚举类型的约束优先级可以使用
内容吸附是指、框架和内容的自然大小的匹配程度、吸附值高、则视图和呈现的内容大小越接近
删除:removeFromSuperView 或者 removeContraints
注意、使用removeContraints不能使用两个等价的约束、而要使用约束的指针、比如
添加一个新的约束
使用
可以使用变量的方式保存
如
然后使用
或者比较两个约束、然后删除在数学上和传递的参数匹配的约束
视图1.属性(关系) 视图1.属性(关系) * 乘数 + 常数
视图将约束作为对象读取、如果两个约束在内存的不同位置、那么即使他们的内容完全相同、系统也会认为他们是不同的约束、这时如果想删除、就可以使用比较功能来实现
目前我们公司使用的pureLayout、基于原生的布局系统的category、使用比较方便、而且不太用担心停止更新的情况(即使停止更新、也是使用的原生布局、是向后兼容的、最多一些新的方法不能使用、但不会出问题)
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会是这样的:
三种布局方式的比较
目前iOS的布局方式有三种、分别是code frame、autoResize、autoLayout。code frame是最原始的方法、可以做到非常精确到设定、但是当view非常多、层次非常复杂的时候、重新计算frame会变成非常大的工作量。
autoResizing是苹果之后推出的应对多尺寸屏幕适配的方法、但是有两个缺点
只能调整父view 和子view的关系、而不能调整两个子view的关系
只能应对外部变化、即父view的大小变化、而不能应对内容变化
而autolayout能够应对code frame 和 autoResizing所不能做到的功能、有以下优点:
同时应对外部变化和内部变化
更符合我们的思路、因为它是是描述性的、不关心具体的frame、只关心ui之间的关系、所以我们只要按照布局时的思路来写就可以了、系统会自动计算最终的布局
向后兼容和之前的frame布局可以同时存在、使用的成本就大大减小了
大大减少了布局的工作量、尤其是当布局大量变化的时候
约束 constraint
我们知道、autolayout就是由view之间的约束组成、那么什么是约束呢?约束是描述两个view之间关系的语句、它的重点就是、两个view之间有哪些联系和影响、使用下面的列子说明:
名称 | 内容 |
---|---|
Item1 | 你希望设定的item |
Attribute1 | item1的属性 |
Multiplier | 倍数 |
Item2 | 影响item1的item |
Attribute2 | item2的属性 |
constant | 常量 |
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、使用比较方便、而且不太用担心停止更新的情况(即使停止更新、也是使用的原生布局、是向后兼容的、最多一些新的方法不能使用、但不会出问题)
相关文章推荐
- JVM中的本地方法栈(Native Method Stacks)和Java虚拟机栈(Java Virtual Machine Stacks)
- Android 判断是否有外网连接
- 闹元宵 购课程! 讲师限时一天大回馈!2016改变从学习开始~
- 浏览器模式与文档模式 及其开发中处理方式
- Python教程学习简记12--Python Partial function 偏函数
- java23中设计模式
- Python:2D画图库matplotlib学习总结
- redis/分布式文件存储系统/数据库 存储session,解决负载均衡集群中session不一致问题
- 如何禁用IE10的明文显示密码和快速清除功能
- Windows服务的配置与安装
- 打印九九乘法表算法-java
- windows下mysql中文显示乱码
- JSON_Message_Thread_AlterDialog_HTTP
- ZeroMQ,史上最快的消息队列 —– ZMQ的学习和研究
- service和thread的区别,何时用service,何时用thread?
- 小儿头痛
- HDU1506 Largest Rectangle in a Histogram
- codeforces 19D 线段树+set
- android怎样写一个循环文字滚动的TextView
- mysql时间格式化,按时间段查询MYSQL语句