iOS-Auto Layout[3]-Stack Views

Stack Views是一种内部定义好了Constraints的View,用于垂直或者水平排列一组控件,可以快速地设计用户界面。有必要的时候,可以增加额外的Constraints到Stack Views中,但是这将增加Layout的复杂度。

Auto Layout和Constraints的原理参考Auto Layout[1]-Constraints

简单StackView

当要设计如下的布局效果时:

AutoLayout-StackView

由于控件都是垂直排列,可以直接使用StackView,将三个控件拖到StackView中:

AutoLayout-StackView

设置StackView与SuperView的Constraints:

1
2
3
4
Stack View.Leading = Superview.LeadingMargin
Stack View.Trailing = Superview.TrailingMargin
Stack View.Top = Top Layout Guide.Bottom + Standard
Bottom Layout Guide.Top = Stack View.Bottom + Standard

设置StackView的属性:

AutoLayout-StackView

设置ImageView的属性:

AutoLayout-StackView

由于,图片的优先级较小,文字显示的优先级较高,设置ImageView的CHCR比其他控件低:

AutoLayout-StackView

复杂StackView

当要设计如下的布局效果时:

AutoLayout-StackView

由于控件较复杂,需要嵌套多个StackView:

AutoLayout-StackView

设置StackView与SuperView的Constraints:

1
2
3
4
5
6
7
Root Stack View.Leading = Superview.LeadingMargin
Root Stack View.Trailing = Superview.TrailingMargin
Root Stack View.Top = Top Layout Guide.Bottom + 20.0
Bottom Layout Guide.Top = Root Stack View.Bottom + 20.0
Image View.Height = Image View.Width
First Name Text Field.Width = Middle Name Text Field.Width
First Name Text Field.Width = Last Name Text Field.Width

设置StackView的属性:

AutoLayout-StackView

设置CHCR:

AutoLayout-StackView

这里,需要注意的是,由于StackView非常松散地扩张其内容,所以,为了保证图片跟上方的StackView等高,垂直方向的CR必须非常低,另外,图片是正方形,所以水平方向的CR也必须非常低,如图中的48。

动态控制StackView

除了在Storyboard中直接控制StackView外,也可以在代码中进行控制,例如:

1
2
3
4
5
6
7
.h:
@property (weak, nonatomic) IBOutlet UIStackView *stackView;

.m:
UILabel *label = [UILabel new];
label.text = @"hello";
[_stackView addArrangedSubview:label];

几个注意点:

  • 如果View的Hidden为YES时,依然在StackView的ArrangedSubviews数组中;
  • 添加一个View到StackView的ArrangedSubviews数组中,会自动将其加入到View的结构树中;
  • 从ArrangedSubviews数组中删除一个View不会自动将其从View的结构树中删除,反过来,从结构树中删除将会直接从ArrangedSubviews数组中删除;
  • 在iOS中,View的Hidden变化并没有动画,而如果View处于ArrangedSubviews数组中,Hidden变化将会自动产生动画。