UIStackView简单理解和使用
一、UIStackView简介
UIStackView是iOS9中新增的API,类似于Android中的线性布局。UIStackView提供了一个高效的接口用于平铺一行或一列的视图组合。对于嵌入到StackView的视图,你不用再添加自动布局的约束了。Stack View管理这些子视图的布局,并帮你自动布局约束。也就是说,这些子视图能够适应不同的屏幕尺寸。此外,你可以嵌入一个stack View到另一个stack view中来创建更为复杂的用户界面。不要误解我的意思,这并不意味着你就不需要处理自动布局了。你仍旧要定义一些布局约束来约束stack view。它只是帮你节约了为每个UI元素创建约束的时间,同时它更容易的从布局中添加/删除一个视图。
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.frame = CGRectMake(100, 100, 200, 50);
stackView.backgroundColor = [UIColor redColor];
UILabel *lable = [[UILabel alloc] init];
lable.text = @“测试”;
lable.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
[stackView addArrangedSubview:lable];
- 1、 UIStackView是UIView的子类,但backgroundColor 设置是无效的
- 2、UIStackView是通过它的 arrangedSubviews属性列表来管理view的, 而通过- (void)addArrangedSubview:(UIView *)view就可以将view添加到arrangedSubviews中
- 3、 stack view 用自动布局的方式来确定其子view的大小和位置。
-
4、在水平方向上,第一个view的左边缘和stack view的左边缘是对齐的,最后一个view的右边缘和stack view的右边
边缘是对齐的,
截屏2020-08-20 上午10.22.14.png
如果你再去这样给子view设置左边的约束,自然是无效的
[lable mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(stackView).offset(20);
}];
控制台也会打印这样约束冲突的错误
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
因此需要注意的是,UIStackview内部也是通过约束来实现的,因此,必须提供足够的且正确的约束才能使用好它。
二、axis
@property(nonatomic) UILayoutConstraintAxis axis;
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0,
UILayoutConstraintAxisVertical = 1
};
管理子view的布局方向,属性值决定了子view的排布是按水平方向依次排布,还是沿着竖直方向依次排布。默认是UILayoutConstraintAxisHorizontal
stackView.axis = UILayoutConstraintAxisHorizontal;
截屏2020-08-20 下午1.50.54.png
stackView.axis = UILayoutConstraintAxisVertical;
截屏2020-08-20 下午1.51.38.png
三、distribution
property(nonatomic) UIStackViewDistribution distribution;
typedef NS_ENUM(NSInteger, UIStackViewDistribution) {
UIStackViewDistributionFill = 0,
UIStackViewDistributionFillEqually,
UIStackViewDistributionFillProportionally,
UIStackViewDistributionEqualSpacing,
UIStackViewDistributionEqualCentering,
} ;
决定着在轴线方向上是怎么样布局的,默认值是UIStackViewDistributionFill
- 1、UIStackViewDistributionFill:子view填满主轴方向StackView空间。
- 2、 UIStackViewDistributionFillEqually:使所有子视图在轴方向上等宽或等高
- 3、UIStackViewDistributionFillProportionally:根据原先子视图的比例来拉伸或压缩子视图的宽或高
- 4、UIStackViewDistributionEqualSpacing:所有子视图中间的间隔保持一致
- 5、UIStackViewDistributionEqualCentering: 所有子视图的中心之间的距离保持一致
3.1、UIStackViewDistributionFill
1、stackView 大小约束确定
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionFill;
stackView.frame = CGRectMake(30, 100, 300, 300);
for (int i=0; i<4; i++) {
UIView *view =[[UIView alloc]init];
[stackView addArrangedSubview:view];
view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
if (i<3) {
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@90);
}];
}
}
- stackView大小约束确定:通过指定子元素的大小约束或者固有大小来布局子元素,当所有子元素超出stackView或者没有充满stackView,会自动根据约束的优先级对某一个子view拉伸或者压缩;当约束优先级不能确定时,就按照排布的顺序,对最后一个view拉伸或者压缩;
2、stackView 大小不确定
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionFill;
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.offset(10);
}];
for (int i=0; i<4; i++) {
UIView *view =[[UIView alloc]init];
[stackView addArrangedSubview:view];
view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.height.equalTo(@90);
}];
stackView 大小不确定:所有的子元素指定大小约束,会自动根据子元素调整stackView的大小。
3.2、 UIStackViewDistributionFillEqually
1、stackView 大小约束确定
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionFillEqually;
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.offset(10);
make.height.equalTo(@200);
make.width.equalTo(@300);
}];
for (int i=0; i<4; i++) {
UIView *view =[[UIView alloc]init];
[stackView addArrangedSubview:view];
view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
}
2、stackView 大小约束不确定
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionFillEqually;
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.offset(10);
}];
for (int i=0; i<4; i++) {
UIView *view =[[UIView alloc]init];
[stackView addArrangedSubview:view];
view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@60);
make.height.equalTo(@300);
}];
}
3、 UIStackViewDistributionEqualSpacing
1、stackView 大小约束确定
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionEqualSpacing;
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.offset(10);
make.width.equalTo(@300);
make.height.equalTo(@100);
}];
for (int i=0; i<4; i++) {
UIView *view =[[UIView alloc]init];
[stackView addArrangedSubview:view];
view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@30);
}];
}
2、stackView 大小约束不确定
UIStackView *stackView = [[UIStackView alloc] init];
[self.view addSubview:stackView];
stackView.spacing = 20;
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionEqualSpacing;
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.offset(10);
make.height.equalTo(@100);
}];
for (int i=0; i<4; i++) {
UIView *view =[[UIView alloc]init];
[stackView addArrangedSubview:view];
view.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@30);
}];
}
4、 spacing
- 1、Fill distributions( UIStackViewDistributionFill 、 UIStackViewDistributionFillEqually、 UIStackViewDistributionFillProportionally): spacing确定了子view的严格间距
- 2、other(UIStackViewDistributionEqualSpacing、 UIStackViewDistributionEqualCentering):spacing作为了 最小间距,可能子view之间的间距会更大一些。
四、alignment
@property(nonatomic) UIStackViewAlignment alignment;
typedef NS_ENUM(NSInteger, UIStackViewAlignment) {
UIStackViewAlignmentFill,子视图填充StackView
UIStackViewAlignmentLeading,子视图左对齐(axis为垂直方向而言)
UIStackViewAlignmentTop = UIStackViewAlignmentLeading,子视图顶部对齐(axis为水平方向而言)
UIStackViewAlignmentFirstBaseline, 按照第一个子视图的文字的第一行对齐,同时保证高度最大的子视图底部对齐(只在axis为水平方向有效)
UIStackViewAlignmentCenter,子视图居中对齐
UIStackViewAlignmentTrailing,子视图右对齐(axis为垂直方向而言)
UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing,子视图底部对齐(axis为水平方向而言)
UIStackViewAlignmentLastBaseline, 按照最后一个子视图的文字的最后一行对齐,同时保证高度最大的子视图顶部对齐(只在axis为水平方向有效)
} ;
决定了垂直轴方向的布局
截屏2020-08-20 下午5.03.34.png
UIStackView *containerView = [[UIStackView alloc] init];
containerView.axis = UILayoutConstraintAxisHorizontal;
containerView.alignment = UIStackViewAlignmentTop ;
containerView.spacing = 10;
NSMutableString *testString =[[NSMutableString alloc]init];
for (int i=0; i<5; i++) {
UILabel *lable = [[UILabel alloc] init];
lable.backgroundColor = [UIColor colorWithRed:random()%256/255.0 green:random()%256/255.0 blue:random()%256/255.0 alpha:1];
[containerView addArrangedSubview:lable];
NSString *str = [NSString stringWithFormat:@"%d",I];
[testString appendString:str];
lable.text = testString;
}
[self.view addSubview:containerView];
[containerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.offset(100);
make.centerX.equalTo(self.view);
make.height.equalTo(@100);
}];
截屏2020-08-20 下午5.24.44.png