UIStackView文档翻译

前段时间有空,回顾一下知识点。就去官网看了一下UIStackView的文档,扫一下知识盲区。以下为翻译:

UIStackView
一种流式布局,管理横向或者纵向的视图集合。继承于UIView。

概述:
Stack view 让你使用强大的自动布局,创建能够自动适配设备任何方向,大小,和各个屏幕尺寸空间的用户视图。Stack view管理ArrangedSubviews属性中的所有视图布局。这些视图按照ArrangedSubviews的顺序,沿着stack view的轴进行排列。实际的布局取决于stack view的轴(Axis)、分布(Distribution)、对齐(Alignment)、间距(Spacing)和其他属性。


图一.png

打开StoryBoard使用stack view。从控件对象库中,拖动任意一个水平或者垂直的Stack View,放到需要的位置。然后拖动视图或者控制器,放到StackView中。如果有必要,还可以放多个视图或者控制器。IB会根据StackView的视图内容来重新计算StackView的大小。你也能够通过调整StackView的属性来控制子视图的外观大小。
注意:你要约束好StackView的位置和大小(可选)。StackView才能管理好子视图的布局和大小。

StackView和自动布局
StackView使用自动布局来对子视图调整位置和大小。将第一个子视图和最后一个子视图沿着StackView的轴进行边缘对齐排列。在水平的StackView中,第一个子视图的左边距固定在StackView的左边,最后一个子视图的右边距固定在StackView的右边。相同的,在垂直的StackView中,子视图的上下边距分别对应StackView的上下边距。如果设置StackView的layoutMarginsRelativeArrangement属性为YES,StackView的子视图布局就不是固定到StackView的边距,而是使用设置的相关边距。

除了UIStackViewDistributionFillEqually属性外的分布(Distribution)属性,子视图都是按照自身的大小,按照StackView的轴进行排列。但是UIStackViewDistributionFillEqually属性,就会将StackView轴方向的宽度平分给子视图,让子视图重新计算大小,填满整个StackView的轴方向。如果可以,StackView也会按照子视图中最大的一个宽度,强制拉伸所有的子视图到最大的宽度。

除了 UIStackViewAlignmentFill属性外的对齐(Alignment)属性,子视图都是按照自身的大小,来填充子视图垂直于StackView方向轴的宽度大小。而 UIStackViewAlignmentFill属性,会重新计算子视图来填充满StackView垂直于轴方向的宽度。如果可能,StackView会用子视图垂直stack轴方向的最大宽度为标准,拉伸其他子视图,用来填满垂直于stack方向轴的宽度。(emmmmmmmm,垂直于轴方向的,直译起来别扭,但是又找不到很好的形容词。什么是垂直于轴方向呢,就是如果StackView是垂直的,垂直于StackView轴方向就是水平,这个水平可以理解成视图的宽度,此时子视图的宽度要填充满StackView的宽度)

图二.png

StackView的位置和大小
即使StackView允许子视图不直接使用自动布局而直接添加,但是StackView自身也需要用自动布局。这就意味着至少需要两个相邻边距,用来调整StackView的边距并确定位置。不需要额外的约束,系统就会根据StackView的子视图内容来自动计算出StackView的大小。

1、沿着StackView的轴方向,计算其轴方向宽度的方法,是所有子视图宽度的总和加上,每个子视图之间的间距总和。即StackView轴方向宽度=子视图宽度总和+子视图间距总和。

2、垂直于StackView轴方向,它的宽度以子视图中一个最大宽度的子视图为准。

3、如果StackView的layoutMarginsRelativeArrangement属性为YES。则StackView的大小,就是按照子视图各自的大小和约束边距逐个相加。因为子视图的大小不受StackView的属性约束。

你也可以为StackView本身添加宽度和高度约束。这样的话,StackView就会调整子视图的布局和大小,用来填充满StackView的区域。子视图的准确布局,依赖于StackView的属性。如果遇到StackView内容空间不足或者填不满的情况,请参阅UIStackViewDistribution和UIStackViewAlignment枚举说明。

你可以使用第一条或者最后一条基线来定位一个StackView,而不使用顶部,底部,Y轴中心店对齐的方式来定位。比如StackView处理大小,他的基线是依靠StackView的内容来计算的。

水平的StackView,返回一个最高层级视图的viewForFirstBaselineLayout和viewForLastBaselineLayout方法。如果最高层级的视图也是一个StackView,那么他返回的结果,就是这个StackView的viewForFirstBaselineLayout or viewForLastBaselineLayout 方法。

垂直的StackView,返回的是第一个子视图的viewForFirstBaselineLayout和最后一个子视图的viewForLastBaselineLayout。如果第一个或者最后一个之中,有一个是SatckView,那么这个结果就是使用这个StackView的viewForFirstBaselineLayout 或者 viewForLastBaselineLayout。

注意:
基线对齐仅适用于,子视图高度和StackView的高度匹配的情况。如果子视图过大或者太小,基线就会错误的定位。

常见的几个StackView布局
以下是常见的,使用StackView为视图内容布局的案例。
1、仅仅定义位置。通过调整与父视图的两个边距,来确定StackView的位置。例如,StackView的大小依赖于子视图的宽高。这个方法适用于,添加视图后,视图的排列不乱,且StackView的大小适应内容视图大小。
如下图:通过固定与父视图的上边距和左边距来展示StackView。两个label对齐StackView布局,中间间距为8pt,左对齐StackView。


图三.png

2、沿着轴来确定StackView的大小。例如,沿着StackView的轴方向固定两个与父视图的边距,确定好SatckView的大小。你也需要固定另外一个边距,来确定StackView的位置。StackView的大小和位置,就取决于内容沿着轴方向去填满的宽度,包括子视图的间距。然而,那个不确定的间距就取决于最大的子视图的大小。

如下图:


图四.png

3、确定好垂直StackView轴方向的大小。这个与上一个例子类似,但是你要固定垂直于轴方向的边距,并且固定轴方向的一个边距。StackView的轴方向大小就会随着你添加子视图而增长或压缩。除非使用fill Equally 属性,否则StackView的大小,就等于所有子视图自己固有的大小总和。垂直于其轴方向,子视图就会随着StackView的对应的对齐方式,布局好自己的位置。

如下图:展示了垂直的SatckView,里面有四个label和一个button。StackView使用了8pt的间距以及居中对齐的对齐方式。StackView的高度,也会随着子视图的添加和移除,而变大和缩小。


图五.png

4、定义好位置和大小的StackView。比如,定义好了StackView的四个边距,其子视图就只能在限制的空间内布局。

如下图,展示了一个定义好四个边距的StackView。使用了剧中布局的对齐方式和填充满的属性。StackView让子视图在正中心布局填充满整个SatckView。然而,想要达到这种布局,还需要额外的几个步骤。默认的,在StackView的垂直方向中,会拉伸UILabel而不会拉伸UIImageView。要调增ImageView,使UILabel的内容拥抱优先级低于UIImageView。另外,UIImageView会设置Aspect Fit的填充方式,来维持ImageView的展示比例,以防止图片失真。对UIImageView和StackView添加一个等宽约束,会有助于ImageView在有效的空间里,展示ImageView。


图六.png

管理StackView的外观
UIStackView是UIView的非呈现子类。因此,它不会提供任何的用户操作接口。但是它可以直接自动管理子视图的位置和大小。结果是,一些属性(比如backgroundColor)在StackView没有效果。同样的,不能重写layerClass, drawRect:, or drawLayer:inContext:等方法。

下面有几个如何定义StackView内容布局的属性:

1、axis属性,定义SatckView的布局方向,垂直或者是水平。

2、distribution属性,确定子视图轴方向的布局。

3、alignment属性,确定子视图垂直于轴方向的布局。

4、spacing属性,确定两个子视图之间的最小间距。

5、 baselineRelativeArrangement属性,确定是否从基线,来测量子视图之间的垂直距离。

6、 layoutMarginsRelativeArrangement属性,确定StackView是否相对于其布局边距来布置其排列的子视图。

通常,大家会使用一个StackView来布局几个少量的子视图。但是你也可以使用嵌套的StackView来复杂的视图。例如下图,展示了一个垂直StackView包含两个水平布局的StackView。每一个水平的StackView包含有一个UILabel和一个UITextFiled。


图七.png

你也能够通过给子视图添加额外的约束,来调整子视图的外观。比如,你能使用约束来设置视图的最大或最小的宽高。或者你能够设置视图的宽高比。当子视图布局的时候,UIStackView会使用这些约束。比如,UIImageView有一个宽高比,在image重新布局时,可以使用宽高比强制约束。

注意:
在为UIStackView中的子视图添加约束是,要小心避免约束引用冲突。一般来说,如果一个视图返回的默认大小,是内容给定的尺寸大小,那么你就可以为这个尺寸安全的添加约束。

维护ArrangedViews和SubViews的一致性
StackView会确保,arrangedSubviews属性是subviews属性的子集。以下几点,是StackView必须遵守的规则:

1、StackView添加了视图到ArrangedViews的同时,也会添加到SubViews中。
2、当子视图从StackView中移除时,StackView也会将其从ArrangedViews中移除。
3、从ArrangedViews中移除,不一定会从SubViews中移除。而且StackView不再会管理视图的大小和位置,但是视图仍然在StackView中,在需要的时候也会被渲染,出现在屏幕上。

即使ArrangedSubViews数组总是SubViews的子集,但是他自己的数组顺序也是保持独立的。
1、arrangedViews数组的顺序,在视图出现在StackView中的时候被确定。对于水平StackView来说,子视图会按照顺序布局,低索引的排在高索引之前。正常来说,它会从左到右依次排列。在垂直的StackView中,视图会从高到低,按照索引依次排列。
2、subViews的顺序定义了subViews的Z轴顺序。如果子视图重叠,视图就会按照谁索引低的在索引高的上面来进行排列。

动态修改StackView的内容视图
当子视图被添加、移除、插入到ArrangedSubViews数组中,或者ArrangedSiubViews中的子视图hidden属性被改变时,StackView会自动更新布局。

如果StackView的任意一个属性被改变,StackView也会自动响应的作出改变。比如,你可以通过修改axis属性,来动态修改StackView的方向。

你可以将arrangedSubViews的hidden属性修改和StackView的属性修改,这两个方法,放到动画的方法块中,让这两个改变产生动画。

最后,你能够在IB中,为StackView许多的属性添加大小类的特定值。系统会在这些大小类被改变时,自动添加动画。

你可能感兴趣的:(UIStackView文档翻译)