ios 布局是个神奇的东西。像我这种没有ios基础并且是半路出家的人来说,真是神奇的东西呢。
首先我们来看看 三种不同的设置
项目图中设置大家都看懂了吧!如果不懂没关系 看看下面的解释
-
第一个布局约束了视图的前沿相对于其超视图的前沿。它也给视图一个固定的宽度。后缘的位置可以基于超视图的尺寸和其他约束来计算。
-
第二个布局约束了视图的前沿相对于其超视图的前沿。它也限制了视图相对于超视图的后沿的后沿。视图的宽度可以根据超级视图的大小和其他约束来计算。
-
第三个布局约束了视图的前沿相对于其超视图的前沿。它也中心对齐视图和超视图。宽度和后缘的位置都可以基于超视图的尺寸和其他约束来计算。
首先来看看同种空间三种效果:
竖屏
横屏
我们其中以后个控件的属性
1-1
1-2
对于老手来说这些一看就懂。可是对于菜鸟来说 这些都是什么呢?没关系 我们一步一步去分析
1动布局中的值总是以点为单位。但是,这些测量的确切含义取决于所涉及的属性和视图的布局方向。
对照图1-1
宽固定为88
开头距离safearea 距离为166
顶部距离safearea 距离为102
还没懂 没关系 看看这个例子
自动布局属性
在自动布局中,这些属性定义了一个可以被约束的特征。一般来说,这包括四个边(前导,尾随,顶部和底部),以及高度,宽度和垂直和水平中心。文本项目也有一个或多个基准属性。
好了 看上了上面例子可能懂了看看例子
// 设置恒定高度
View.height = 0.0 * NotAnAttribute + 40.0
//设置两个按钮之间的固定距离
Button_2.leading = 1.0 * Button_1.trailing + 8.0
// 调整两个按钮的前缘
Button_1.leading = 1.0 * Button_2.leading + 0.0
// 给两个按钮同样的宽度
Button_1.width = 1.0 * Button_2.width + 0.0
// 在它的父视图的中心观点
View.centerX = 1.0 * Superview.centerX + 0.0
View.centerY = 1.0 * Superview.centerY + 0.0
// 给出一个恒定的长宽比
View.height = 2.0 * View.width + 0.0
现在考虑一些更复杂的事情。想象一下,你想在iPhone上并排显示两个视图。你要确保它们在所有方面都有一个很好的余量,并且它们总是具有相同的宽度。它们也应该在设备旋转时正确调整大小。
以下插图以纵向和横向显示视图:
那么这些约束是什么样的呢?下图显示了一个简单的解决方案:
上述解决方案使用以下约束:
// Vertical Constraints
Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Blue.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Blue.bottom + 20.0
// Horizontal Constraints
Red.leading = 1.0 * Superview.leading + 20.0
Blue.leading = 1.0 * Red.trailing + 8.0
Superview.trailing = 1.0 * Blue.trailing + 20.0
Red.width = 1.0 * Blue.width + 0.0
遵循较早的经验法则,该布局具有两个视图,四个水平约束和四个垂直约束。虽然这不是一个可靠的指导,但它是一个快速的迹象表明,你在正确的轨道上。更重要的是,约束唯一地指定了两个视图的大小和位置,产生了不含糊的可满足的布局。删除任何这些约束,布局变得模糊。添加额外的约束,您可能会引入冲突。
不过,这不是唯一可能的解决方案。这是一个同样有效的方法:
将蓝框的顶部和底部固定到其超视图,而不是将蓝框的顶部与红框的顶部对齐。同样,您将蓝色框的底部与红色框的底部对齐。约束如下所示。
// Vertical Constraints 垂直约束
Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Red.top = 1.0 * Blue.top + 0.0
Red.bottom = 1.0 * Blue.bottom + 0.0
//Horizontal Constraints 水平约束
Red.leading = 1.0 * Superview.leading + 20.0
Blue.leading = 1.0 * Red.trailing + 8.0
Superview.trailing = 1.0 * Blue.trailing + 20.0
Red.width = 1.0 * Blue.width + 0.0
该示例仍然有两个视图,四个水平约束和四个垂直约束。它仍然产生一个不含糊的,可以满足的布局。
但哪个更好?
这些解决方案都生成有效的布局。那哪个更好?
不幸的是,客观上证明一种方法严格优于另一种方法实际上是不可能的。每个人都有自己的长处和短处。
当视图被移除时,第一种解决方案更加健壮。从视图层次结构中删除视图也会删除引用该视图的所有约束。所以,如果你删除了红色的视图,蓝色的视图留下了三个约束的地方。您只需要添加一个约束,并再次有一个有效的布局。在第二个解决方案中,删除红色视图将使蓝色视图只有一个约束。
另一方面,在第一种解决方案中,如果要使视图的顶部和底部对齐,则必须确保它们的顶部和底部约束使用相同的常量值。如果你改变一个常数,你必须记得改变另一个。
抗压缩和抗拉伸效果
抗压缩(Compression-Resistance) 和抗拉伸(Content-Hugging)效果是跟自身内容尺寸关联在一起的,如图3.4所示,抗压缩定义了视图抗压缩的优先级,优先级越大,表示越难压缩;抗拉伸则定义了视图抗拉伸的优先级,优先级越大,则越难被拉伸。抗压缩和抗拉伸的优先级是针对横竖两个方向的,每个方向都有一个优先级。默认的View和Button的抗压缩优先级为750,抗拉伸优先级为250。从优先级大小可以看出来,拉伸一个View比压缩一个View容易。这也符合我们的期望,比如我们期望拉伸一个按钮大于其自身内容尺寸,而不是缩小按钮尺寸导致内容显示不全。
// Compression Resistance
View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
View.width >= 0.0 * NotAnAttribute + IntrinsicWidth
// Content Hugging View.height <= 0.0 * NotAnAttribute + IntrinsicHeight View.width <= 0.0 * NotAnAttribute + IntrinsicWidth
对于两个控件来说,为了满足Auto Layout的约束,通常会优先压缩那个抗压缩优先级小的控件来适应视图的布局。
下面看一个例子,我们在视图中添加一个Label和一个Text Field。然后分别设置了Label的左上的约束和Text Field的右上约束,然后设置Label和Text Field的间距为20。约束关系我们可以看到左边的5个等式,因为Label和Text Field都有自身内容尺寸,所以这5个等式已经可以完成布局了。在这个例子中我们看到Text Field被拉伸了,而Label还是保持自身内容尺寸的,这是因为Label的默认抗拉伸优先级为251大于Text Field的默认抗拉伸优先级250,因此Label更难被拉伸,所以看到的是Text Field被拉伸了。那如果我们把Text Field的抗拉伸优先级改为252,则最终运行的界面如图3.5.4所示。
接下来再看一个Image View的例子,可以看看自身内容尺寸和CRCH对Image View的影响。这里我在Image View里面加了个apple.jpg的图片,图片原始尺寸为241*300
。开始的时候我设置Image View水平垂直居中,不设置宽度高度,则Image View的宽度和高度为图片原始尺寸241和300。然后再添加一个宽度约束,设置图片宽度为300。由于显示添加的约束的默认优先级为1000,而Image View的抗拉伸的优先级为251,所以会以显示添加的约束为准,图片宽度会被拉升到300。而如果我们把显示添加的宽度约束的优先级改成250,则图片宽度会被设置为原始宽度241。
4 更多例子
4.1 两个宽度相等的View
约束关系:
1.Yellow View.Leading = Superview.LeadingMargin
2.Green View.Leading = Yellow View.Trailing + Standard
3.Green View.Trailing = Superview.TrailingMargin
4.Yellow View.Top = Top Layout Guide.Bottom + 20.0
5.Green View.Top = Top Layout Guide.Bottom + 20.0
6.Bottom Layout Guide.Top = Yellow View.Bottom + 20.0
7.Bottom Layout Guide.Top = Green View.Bottom + 20.0
8.Yellow View.Width = Green View.Width
4.2 两个宽度不等的View
约束关系:
1.Purple View.Leading = Superview.LeadingMargin
2.Orange View.Leading = Purple View.Trailing + Standard
3.Orange View.Trailing = Superview.TrailingMargin
4.Purple View.Top = Top Layout Guide.Bottom + 20.0
5.Orange View.Top = Top Layout Guide.Bottom + 20.0
6.Bottom Layout Guide.Top = Purple View.Bottom + 20.0
7.Bottom Layout Guide.Top = Orange View.Bottom + 20.0
8.Orange View.Width = 2.0 x Purple View.Width
4.3 自身内容尺寸
约束:
1.Name Label.Leading = Superview.LeadingMargin
2.Name Text Field.Trailing = Superview.TrailingMargin
3.Name Text Field.Leading = Name Label.Trailing + Standard
4.Name Text Field.Top = Top Layout Guide.Bottom + 20.0
5.Name label.Baseline = Name Text Field.Baseline
这个例子跟前面提到的类似,注意并不需要设置Label和Text Field的宽度和高度。而且默认设置中,Label的抗拉伸的优先级251比Text Field的250更高,所以最终看到的效果是Text Field被拉伸了。
4.4 自适应View
约束:
1.Blue View.Leading = Superview.LeadingMargin
2.Blue View.Trailing = Superview.TrailingMargin
3.Blue View.Top = Top Layout Guide.Bottom + Standard (Priority 750)
4.Blue View.Top >= Superview.Top + 20.0
5.Bottom Layout Guide.Top = Blue View.Bottom + Standard (Priority 750)
6.Superview.Bottom >= Blue View.Bottom + 20.0
前面的例子都是=
的约束,这个例子加了>=
的约束。
注意到我们设置的>=
的约束4优先级比约束3要高,约束6的优先级比约束5的高,这样如果显示状态栏(模拟器里面竖屏的时候),我们知道状态栏的高度为20,那么这时约束3满足的时候,也就是Blue View的y坐标为28(状态栏高度20+标准距离8),这时约束4也满足,因此会选择约束3这个优先级较低的约束。如果不显示状态栏(模拟器里面横屏的时候),则此时只能满足约束4,无法满足约束3。不过Auto Layout引擎会选择一个最接近的约束,也就是设置Blue View的y坐标为20。
更多例子:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSimpleConstraints.html#//apple_ref/doc/uid/TP40010853-CH12-SW1
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/ViewswithIntrinsicContentSize.html#//apple_ref/doc/uid/TP40010853-CH13-SW1
Size Class例子:
https://www.raywenderlich.com/113768/adaptive-layout-tutorial-in-ios-9-getting-started
使用代码和VFL来添加约束可以参见:
http://blog.csdn.net/pucker/article/details/45070955
http://blog.csdn.net/pucker/article/details/45093483
参考
- Understanding Auto Layout
- iOS8 Auto Layout布局
- https://www.jianshu.com/p/c6541ff0bdaf?nomobile=yes