iOS - UIStackView 布局 详解

本文详细介绍了UIStackView的概念、用途和特点,包括它的axis、alignment、distribution和spacing属性。UIStackView简化了界面布局,支持自动适应和多种子视图排列方式。通过实例展示了不同分布属性的效果,并解释了如何添加和移除子视图。此外,还强调了使用隐藏子视图实现动态布局的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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));

具体显示效果如下:
在这里插入图片描述
fill


在这里插入图片描述

top


在这里插入图片描述

center


在这里插入图片描述
bottom


在这里插入图片描述
first base line


在这里插入图片描述
last base line


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后显示效果:
在这里插入图片描述
UIStackViewDistributionFill

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

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

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

UIStackViewDistributionFillProportionally

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

UIStackViewDistributionEqualSpacing

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

UIStackViewDistributionEqualCentering

4. spacing

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

在这里插入图片描述

三、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,根据动态拉伸规则,灵活使用组件。

例如:
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值