首页 > 代码库 > iOS AutoLayout解析

iOS AutoLayout解析

==========AutoLayout && Layout Constraints=====(available 6.0)

--AutoLayout是一种基于约束的,描述性的布局系统。 Auto Layout Is a Constraint-Based, Descriptive Layout System.

--工作原理:Auto Layout用所有的这些constraints来对你所有的view做一些数学计算以致view达到一个理想的位置以及尺寸。 你不再需要自己来设置view的frame-Auto Layout会帮你做这一切-完全基于你对view所设置的constraints

--理念:通过目的来设计.当你通过目的来设计时, 你在表达的是你想要达到的目标是什么而不是如何来完成目标。在以前会是这么个说法:“这个按钮的左上角的坐标是(20, 230)”, 现在你可以这么表达了:“这个按钮在它的superview中垂直居中,把他放置在离它的superview左边缘的一个固定位置。”

--与Autosizing masks联系区别

--Autosizing masks是AutoLayout的子集。

--1.AutoLayout可以指定任意两个view的相对位置,而不需要像Autoresizing Mask那样需要两个view在直系的view hierarchy中。
--2.AutoLayout不必须指定相等关系的约束,它可以指定非相等约束(大于或者小于等);而Autoresizing Mask所能做的布局只能是相等条件的。
--3.AutoLayout可以指定约束的优先级,计算frame时将优先按照满足优先级高的条件进行计算。

--使用Autosizing masks(xib):

--Align:

(选择两个view时可设置) 左边对齐, 右边对齐, 顶部对齐, 底部对齐, 

-----------------------------------------------------------------------
(选择两个view时可设置) x轴中心对齐, y轴中心对齐, 文本底标线对齐,

-----------------------------------------------------------------------
(单选择一个view时可设置)对于父view的x轴中心对齐, 对于父view的y轴中心对齐
-----------------------------------------------------------------------

更新(frame)选项:添加完约束后不进行任何操作  + 在添加约束后重新摆放约束涉及到的view  + 添加约束后重新摆放所有这个容器内的view

确定按钮:选择完上面的项目后点击添加约束

--Pin

上面的十字是"与最近的邻居的约束", 填上数字, 单击虚线变成实线就是要添加这个约束.

这里的"邻居"是将一个包含子view的父view看做一个装了一堆积木的盒子, 积木相对于盒子的边框和其他的积木都作为"邻居"。相当 Editor->Pin里面Horizontal Spacing/vertical spacing 跟Leading/Trailing/Top/Bottom Space to Superview结合

-----------------------------------------------------------------------
(定义的宽高数据约束):宽度指定,高度指定;
-----------------------------------------------------------------------
(定义多个view之间的宽高约束):宽度相同,高度相同;

-----------------------------------------------------------------------
(列表, 多个view之间的对齐约束:等同于前一菜单的内容;
-----------------------------------------------------------------------

更新(frame)选项 + 确定按钮  同上。

--Resolve Auto Layout Issues

(上半部分菜单的操作对象是当前选中的view, 下半部分的操作对象是选中view内的view)
--刷新frame(使用当前已经设置的所有约束),
--刷新约束(根据当前的约束和frame, 更新约束的constant值),
--添加缺失的约束(自动添加系统认为你应该添加却忘记添加的约束, 测试中经常搞出冲突)
--重置为系统建议的约束(清理系统认为重复/冲突的约束, 测试中经常搞出问题)
--清理所有约束(删除对象上绑定的所有约束)

 

--Constraints设置

(在添加约束的时候, 刷新哪些视图)
--同级view和父view
--子view

======备注======

--0.当某个View的constraints太少,计算不出它的位置和尺寸时,xcode会警告(也叫Root View’s Layout Issues)。Resolve a root view’s layout issues by resolving the layout issues of its subviews。详见“dock右上角箭头”(Choose Editor > Show Document Outline > Click the arrow next to the root view with the layout issues)。

--1.Auto Layout能支持不同语言;

--2.固有尺寸内容:在 Auto Layout 里会先问你的空间他们有多大,然后在基于空间给出的信息将他们展示到屏幕上去。你也可以不使用它,但你要明确设置这个空间的Width 或者 Height constraint。如果你这么做了,那么 Interface Builder 为自动生成一个你设置的constraint。如果想要再次恢复固有内容尺寸的话,你只需重新使用Size to Fit Content 

--3.约束和约束之间会冲突, 无论是xib和xib, xib和代码, 代码和代码. 当某个View有太多的constraints,得到错误 “Unable to simultaneously satisfy constraints”,表示有冲突。

--4.约束冲突系统自动会解决, 通常依靠的是权级, 但是由于一般情况使用无法确定某一约束应该处于什么权级, 所以很难设置正确的权级以应对冲突.
--5.约束冲突, 在ios6上未见crash, 在ios7上偶发crash.

--6.有一种警告“Frame for "XX" will be different at run time.”。它的Expected  frame只是你在Size inspector 里面设置的,Actual是根据你添加constraints算出来的,解决警告只需在“Resolve Auto Layout Issues”里面刷新一下frame,讲Expected变为Actual的。

 

[NSLayoutConstraint constraintWithItem:(id)item
attribute:(NSLayoutAttribute)attribute
relatedBy:(NSLayoutRelation)relation
toItem:(id)otherItem
attribute:(NSLayoutAttribute)otherAttribute
multiplier:(CGFloat)multiplier
constant:(CGFloat)constant]


参数说明:
第一个参数:指定约束左边的视图view1
第二个参数:指定view1的属性attr1,具体属性见文末。
第三个参数:指定左右两边的视图的关系relation,具体关系见文末。
第四个参数:指定约束右边的视图view2
第五个参数:指定view2的属性attr2,具体属性见文末。
第六个参数:指定一个与view2属性相乘的乘数multiplier
第七个参数:指定一个与view2属性相加的浮点数constant

这个函数的对照公式为:
view1.attr1 <relation> view2.attr2 * multiplier + constant

注意:
1.如果你想设置的约束里不需要第二个view,要将第四个参数设为nil,第五个参数设为NSLayoutAttributeNotAnAttribute

举例:
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:view2
attribute:NSLayoutAttributeRight
multiplier:1
constant:10]

翻译过来就是:view1的左侧,在,view2的右侧,再多10个点,的地方。

附视图的属性和关系的值:

typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1, //小于等于
NSLayoutRelationEqual = 0, //等于
NSLayoutRelationGreaterThanOrEqual = 1, //大于等于
};
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1, //左侧
NSLayoutAttributeRight, //右侧
NSLayoutAttributeTop, //上方
NSLayoutAttributeBottom, //下方
NSLayoutAttributeLeading, //首部
NSLayoutAttributeTrailing, //尾部
NSLayoutAttributeWidth, //宽度
NSLayoutAttributeHeight, //高度
NSLayoutAttributeCenterX, //X轴中心
NSLayoutAttributeCenterY, //Y轴中心
NSLayoutAttributeBaseline, //文本底标线

NSLayoutAttributeNotAnAttribute = 0 //没有属性
};

 
 

iOS AutoLayout解析