注册

iOS - UIStackView 布局 详解

一、UIStackView简介

概念:

一个堆叠视图的容器,iOS9的新特性。
用途:StackView及其子视图会自适应界面,减少我们设置约束的工作量。

特点:

  • 类似ContainView,不会渲染到界面上。
  • StackView中的子视图只能朝一个方向进行排布,要么水平要么垂直。
  • StackView支持多层嵌套
  • 约束比StackView的自适应优先级高,可以通过设置约束来调整StackView的布局
  • 支持属性动画
  • 不能滚动

属性:

axis轴: -> 用来设置子视图的排列方式(H/V)
aligement: -> 用来设置子视图的对齐方式
distribution -> 用来设置子视图的分布方式(fill-填充)
spacing -> 子视图之间的间距

二、属性详解

1. axis

主要设置UIStackView布局的方向:水平方向或垂直方向。

typedefNS_ENUM(NSInteger,UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal =0, //水平
UILayoutConstraintAxisVertical =1 //垂直
};
2. alignment

主要设置非轴方向子视图的对齐方式。

typedef NS_ENUM(NSInteger, UIStackViewAlignment) {
UIStackViewAlignmentFill, // 子视图填充
UIStackViewAlignmentLeading, // 子视图左对齐(axis为垂直方向而言)
UIStackViewAlignmentTop = UIStackViewAlignmentLeading, // 子视图顶部对齐(axis为水平方向而言)
UIStackViewAlignmentFirstBaseline, // 按照第一个子视图的文字的第一行对齐,同时保证高度最大的子视图底部对齐(只在axis为水平方向有效)
UIStackViewAlignmentCenter, // 子视图居中对齐
UIStackViewAlignmentTrailing, // 子视图右对齐(axis为垂直方向而言)
UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing, // 子视图底部对齐(axis为水平方向而言)
UIStackViewAlignmentLastBaseline, // 按照最后一个子视图的文字的最后一行对齐,同时保证高度最大的子视图顶部对齐(只在axis为水平方向有效)
} API_AVAILABLE(ios(9.0));

具体显示效果如下:

0323b3477a245707d06f365f437f3154.png

4938d6bb7c576dd1f4ae00d2b0d6ebc7.png

4b847ed5ae48188d15ca7613de235828.png

aca1dd3eb4d169536099db9c39ec3496.png

77f64c6356d921391eb57e4e280c7d3b.png

d928e993c89e05e799f5e5788be99ff5.png

3. distribution

设置轴方向上子视图的分布比例(如果axis是水平方向,也即设置子视图的宽度,如果axis是垂直方向,则是设置子视图的高度)。

typedef NS_ENUM(NSInteger, UIStackViewDistribution) {
UIStackViewDistributionFill = 0,
UIStackViewDistributionFillEqually,
UIStackViewDistributionFillProportionally,
UIStackViewDistributionEqualSpacing,
UIStackViewDistributionEqualCentering,
} API_AVAILABLE(ios(9.0));

下面以
axis = UILayoutConstraintAxisHorizontal,
alignment = UIStackViewAlignmentCenter
为例:

往UIStackView中添加三个UIView:

  1. 第一个UIView设为40*100
  2. 第二个UIView设为80*80
  3. 第三个UIView设为120*60

通过实例来说明每个属性的区别:

(1)UIStackViewDistributionFill = 0,默认属性,轴方向上填充UIStackView。如果axis为水平方向,则所有子视图的宽度等于UIStackView的宽,所以如果只有一个子视图,则子视图的宽度就等于UIStackView的宽,如果有两个子视图,且优先级一样,则会拉伸或压缩某个子视图,使两个子视图的宽度之和等于UIStackView的宽……,如果axis是垂直方向,则所有子视图的高度等于UIStackView的高,必要时会拉伸或压缩某个子视图。

上面是在子视图优先级一致的情况下,如果子视图优先级不一致,则会按优先级从高到低设置子视图的位置,对优先级最低的子视图进行必要的拉伸或压缩。

设置distribution = UIStackViewDistributionFill后显示效果:

79695cc07bb832d38bc4dc0608d4b2aa.png

UIStackViewDistributionFill

如图所示,由于三个子视图的宽度之和不够UIStackView的宽度,优先级又一致,所以第三个子视图被拉伸了。当然,我们可以修改某个子视图的优先级来让其被拉伸。

(2)UIStackViewDistributionFillEqually,该属性设置后使所有子视图在轴方向上等宽或等高。即如果是水平方向,所有子视图都会被必要的拉伸或压缩,使得每个子视图的宽度一致,原来设置的子视图的宽度都会被忽略;如果是垂直方向,所有子视图的高度也会保持一致,如下所示:

508bffdb63416f71943b44b0aed41562.png

UIStackViewDistributionFillEqually

(3)UIStackViewDistributionFillProportionally 该属性设置后会根据原先子视图的比例来拉伸或压缩子视图的宽或高,如实例中三个子视图原先设置的宽度是1:2:3,所以水平方向上显示时,会按照这个比例进行拉伸,如下图所示,拉伸后的宽度依然是1:2:3。

699b2a5662697a43544ef63afa67f152.png

UIStackViewDistributionFillProportionally

(4)UIStackViewDistributionEqualSpacing 该属性会保持子视图的宽高,所有子视图中间的间隔保持一致。如下图所示,图中子视图的间隔(绿线所示的长度)都是一致的。

3c6448f332ac9ba0c479c9c934c8b7fe.png

UIStackViewDistributionEqualSpacing

(5)UIStackViewDistributionEqualCentering 该属性是控制所有子视图的中心之间的距离保持一致,如下图所示,子视图中心点之间的间隔(绿线所示的长度)是一致的。

cd8e84aaa621d7969934c4aae9642283.png

UIStackViewDistributionEqualCentering

4. spacing

该属性控制子视图之间的间隔大小,在distribution前三个属性值设置的情况下,子视图之间是没有间隔,我们可以通过spacing属性显式的设置,如下图在distribution=UIStackViewDistributionFillEqually情况下,设置子视图间隔为10,子视图之间间隔都为10,且子视图依然等宽。

2a1b16e5724a9f1803c705a6344682dd.png

三、subView和arrangedSubView

对于Stack View的子控件添加和移除,我们是这样描述的。

添加 --> (Stack View管理的subview)
addArrangedSubview:
insertArrangedSubview:atIndex: arrangedSubviews
数组是subviews属性的子集。
移除 --> (Stack View管理的subview)
removeArrangedSubview:–>移除是指移除Stack View内部子控件的约束,并没有真正的把控件从父视图上移除。
removeFromSuperview–>从视图层次结构中删除,从父视图上删除

四、知识点小结

1、Axis表示Stack View的subview是水平排布还是垂直排布。
2、Alignment控制subview对齐方式。
3、Distribution定义subview的分布方式。
4、Spacing 为subview间的最小间距。

五、使用技巧

**可以hidden指定子view,根据动态拉伸规则,灵活使用组件。

例如:

d55a87fc00893a172bb26290595d69c4.png


原文链接:https://blog.csdn.net/songzhuo1991/article/details/115626992

0 个评论

要回复文章请先登录注册