UIStackView的使用
2018-10-14 本文已影响0人
ldhonline
image.png
一、了解
二、
一、了解 instric content size
instric content size
表示一个view
的固有的大小,对于UILabel
,UIImageView
,UIButton
这些元素来说,在没有显式设置大小的时候,它总是有一个内容撑开的大小
它们是通过方法-(CGSize)instricContentSize
来返回的,UIView
返回的是一个zeroSize
, 也是大小为0x0, 不可见。
我们可以继承UIView
, 添加一个可以设置的固有大小值,来帮助我们更好的完成布局。
#import "ESView.h"
@implementation ESView
-(CGSize)intrinsicContentSize{
CGSize size = [super intrinsicContentSize];
if(self.es_intrinsicWidth && self.es_intrinsicHeight){
return CGSizeMake(self.es_intrinsicWidth, self.es_intrinsicHeight);
}
return size;
}
@end
二、UIStackView
的特性
UIStackView
是一个容器决定内容排版的布局模式,容器大小的变化,会影响子项的排版。
类似前端体系中的flexbox
的简化版。
-
UIStackView
是一个虚拟容器,它的layer
不被绘制,设置背景、边框、阴影这些外观是无效的。 - 官方中文文档
- 如果我们使用约束,不定义栈视图的大小,只定义位置,这个时候,栈视图不会再改变管理内容的大小,相反,它会自动计算出自己需要的大小,也就是变成了不换行的流式布局。
也就是它会生成一个固有大小,进行内容自适应排版。
三、基本用法
1、创建一个 UIStackView
。
CGSize size = self.view.bounds.size;
UIStackView *sView = [[UIStackView alloc] initWithFrame:CGRectMake(0, 64, size.width, size.height*0.5)];
[self.view addSubview:sView];
可以为它指定固定的 frame
, 也可以添加约束。
2、设置轴向。
sView.axis = UILayoutConstraintAxisVertical;
//sView.axis = UILayoutConstraintAxisHorizontal;
轴向决定了子项的排列方向,分为水平与垂直两种。
3、设置最小间距。
sView.spacing = 2;
默认间距是0, 最小间距的意思就是在子项大小超过容器时,也必须保持的间距,真实间距有可能比它大。
4、设置副轴上子项的对齐方式。
sView.alignment = UIStackViewAlignmentTop;
副轴指的是当前axis的正交轴,对齐方式有上、中、下、两端4类。
-
UIStackViewAlignmentFill
在副轴方向两端对齐,也就是拉伸填满。 -
UIStackViewAlignmentTop
和UIStackViewAlignmentLeading
等效,也就是向开始端对齐。 -
UIStackViewAlignmentBottom
和UIStackViewAlignmentTrailing
类似,也就是向结束端对齐。 -
UIStackViewAlignmentCenter
居中。 -
UIStackViewAlignmentFirstBaseline
,UIStackViewAlignmentLastBaseline
对齐第一行或者最后一行文本的基线。
5、设置内容轴向的宽度或者高度模式。
sView.distribution = UIStackViewDistributionEqualCentering;
它有5种模式:
-
UIStackViewDistributionFill
,默认的全轴填满模式,在保证最小间距的前提下,对子项进行压缩或者拉伸,调节时考虑子项的抗拉伸或者抗压缩级别,如果有的话, 如果没有先从第一个开始拉伸或者压缩。
UIView
默认是可以设置拉伸或者压缩优先级的, 优先级越高的,越先做伸缩。
[view setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
拉伸是无限的,所以一般来说,只会拉伸一个子元素,而压缩是有限的,第一个压缩完了不够,就会压缩第二个。
-
UIStackViewDistributionFillEqually
, 忽略固有大小,全部强制均分填满。 -
UIStackViewDistributionFillProportionally
, 轴向填满,等比例调节。 -
UIStackViewDistributionEqualSpacing
, 等距模式,在大小有剩余的时候,分配到间距上,如果不足,进行压缩。 -
UIStackViewDistributionEqualCentering
, 中心点等距模式,子项的中心点距离相同,间距可能各有不同,固有尺寸越小,边距越大,其实就是先打均分中心点,再绘制。
所有模式都是让子项均匀排版,对于空间剩余的情况下,分配策略不同。
注意它们轴向两端都是贴边的, 也就是说,它的轴向对齐方式就是两端对齐 just
。
可以设置margin来添加外边距
sView.layoutMarginsRelativeArrangement = YES;
sView.layoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
如果只有一个子项的时候,总是被拉伸了。
适应场景
适用于单行或者单列,已知容器大小的前提下排版, 没有
flexbox
那样可以自动换行。
至少要保证轴向大小是可知的,副轴方向可以取决于内容大小。
- 因为拉伸的优先级特性,我们可以设计类似css中的双飞翼、一边固定,一边自适应的排版。