首先,先引入一下一些前人大牛关于al(autolayout)的学习博客,我也是从这些博客中学习过来的。
http://jixuqianxing.github.io/blog/2014/12/16/21041216/ (AutoLayout之可视化布局)
http://jixuqianxing.github.io/blog/2014/11/28/jing-tong-autolayout/ (AutoLayout实用技巧)
http://jixuqianxing.github.io/blog/2014/12/11/20141212/#userconsent# (AutoLayout之纯代码布局)
http://www.cocoachina.com/ios/20141217/10669.html (iOS 8 AutoLayout与Size Class自悟)
上面第一第二个链接是关于可视化界面的;第三个是VFL实现代码布局,一般我是使用可视化布局的,但有时候有的界面会需要调整,会涉及到约束,这个时候会考虑用VFL来修改约束;第四个链接主要是size class的,size class是用来做旋转适配的,文章中的例子很不错,一句代码不用就实现了各种机型不同方向下的不同布局。
现在开始我的补充,以下的举例用作帮助理解,严谨性不做考虑。
1.压缩阻力和内容吸附
如果使用UILabel或者UIButton或者UIImage,在其有文字或图片内容的情况下,使用al,你会发现只需要设置位置就可以,而不用指定宽高。这是因为上面这几个存在内在内容,有压缩阻力和内容吸附(见下图)
上图中标出的第一个是内容吸附,第二个是压缩阻力,上图是默认值。
顾名思义,压缩阻力是指保护视图内容的方式。压缩阻力高的视图能抵抗压缩,不允许内容被剪切。当你设置UILabel或者UIButton(有内容)的约束,位置+固定宽高的时候,发生了约束的冲突或者丢失,许多时候就是因为压缩阻力和固定宽高的约束冲突(解决方法是修改其中一个的优先级)。
内容吸附,是视图防止与其核心内容间作填充或直接伸展其核心内容的作用。像UIButton的文字内容会处于按钮正中央,并且和边缘有一定的距离。当内容吸附优先级小的时候,UIButton的宽高很大,文字内容会被允许伸展,内容吸附优先级高的时候,即使宽高很大,文字内容还是适应自己的内容尺寸,不允许被伸展。
2.优先级
优先级在al中是一个很重要的元素,发生冲突的解决方法就是修改优先级。
举个例子,设置一个UILabel的压缩阻力优先级是1000(最高优先级),UILabel的内容尺寸宽是150,又设置了UILabel的宽是固定100(默认的优先级也是1000),这个时候就发生约束冲突,因为内容尺寸宽比固定宽要大,不可能出现既不压缩内容的情况下固定宽高。解决方法是降低其中一个的优先级,比如降低固定宽的优先级到750,那么运行时,会以内容尺寸宽作为UILabel的宽;如果是降低压缩阻力的优先级,那么会显示固定宽为UILabel的宽。
优先级就是谁高执行谁。
3.倍数Multipliter
上图中设置了一个Label和一个UIButton等宽,如果想设置Label的宽是Button的倍数,可以通过这个属性进行修改。
=====================懒得再写新的而补充内容的分割线=========================
scrollView
scrollView在al中是一个比较特殊的存在,因为它有contentSize这个东西。一般的控件在使用al约束的时候,只需要约束住X、Y和宽高(有的宽高自适应),往其上加子视图也是一样。但往scrollView上加子视图的时候不同,因为有contentSize的存在。
scrollView必须知道自己的内容的宽高,即使你不需要它滚动,也是需要的。
解决方法是往scrollView上添加一个view,作为contentView,即内容视图,设置这个contentView的约束是上下左右贴边(即为0)。这个时候还是会爆约束缺失的红点,因为我们需要为contentView指定滚动的方向,如果是上下滚动,设置约束水平居中,如果是左右滚动,设置约束垂直居中。再指定内容的尺寸,比如是上下滚动,给contentView再加一个高度约束,固定高度,这里可以先随便给个高度,反正后面可以改动。把这个高度约束设为属性(可以通过xib的拉线拉为属性),这里我们可以设置这个高度约束值是我们想要的了,可以是静态指定值,也可以是动态变化的。
可以在viewDidLoad或者在updateViewConstraints里设置y约束值,这个随意。
动画
al的情况下做简单的UIView的动画,比如是某个view高度增高,要有个动画效果,一样先获取这个view的高度约束,可以是先将这个高度约束设为一个属性,也可以是从for循环中循环出这个约束,然后先修改这个约束的值为自己最终想要的值,再执行动画,示例如下
_viewHeightConstraint.constant = 100;
[UIView animateWithDuration:3 animations:^{
[self.view layoutIfNeeded];
}];
layoutIfNeeded的作用是更新约束变化。