OC—初识UIStackView
UIStackView
堆栈视图,是一种存储视图的容器,用于简化和管理子视图的布局与排列,减少我们的约束量
特点:类似于ContainView,不会渲染到界面上、只能朝一个方向排布、支持多层嵌套、可以通过设置约束来调整Stackview的布局、不能滚动
@property(nonatomic) UILayoutConstraintAxis axis;/* The layout of the arrangedSubviews along the axis*/
@property(nonatomic) UIStackViewDistribution distribution;/* The layout of the arrangedSubviews transverse to the axis;e.g., leading/trailing edges in a vertical stack*/
@property(nonatomic) UIStackViewAlignment alignment;/* Spacing between adjacent edges of arrangedSubviews.Used as a strict spacing for the Fill distributions, andas a minimum spacing for the EqualCentering and EqualSpacingdistributions. Use negative values to allow overlap.On iOS 11.0 or later, use UIStackViewSpacingUseSystem (Swift: UIStackView.spacingUseSystem) to get a system standard spacing value. Setting spacing to UIStackViewSpacingUseDefault (Swift: UIStackView.spacingUseDefault) will result in a spacing of 0.System spacing between views depends on the views involved, and may vary across the stack view.In vertical stack views with baselineRelativeArrangement == YES, the spacing between text-containing views (such as UILabels) will depend on the fonts involved.*/
@property(nonatomic) CGFloat spacing;
- axis : 主要设置布局的方向,水平或者垂直
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {UILayoutConstraintAxisHorizontal = 0,//水平排布UILayoutConstraintAxisVertical = 1//竖直排布
} API_UNAVAILABLE(watchos);
- 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));
- distribution: 设置轴方向上子视图的比例,如果axis是水平方向即设置子视图宽度,如果是竖直方向即设置子视图高度
typedef NS_ENUM(NSInteger, UIStackViewDistribution) {UIStackViewDistributionFill = 0,//默认值,轴方向上填充,会拉伸子视图(根据子视图的优先级)UIStackViewDistributionFillEqually,//所有子视图在轴方向等宽或者等高,原来子视图的高度或宽度都会忽略UIStackViewDistributionFillProportionally,//根据原来子视图的比例拉伸子视图的宽或者高UIStackViewDistributionEqualCentering,//所有子视图的中心距离保持一致
} API_AVAILABLE(ios(9.0)) API_UNAVAILABLE(watchos);
- Spacing: 两个视图之间的间距
使用
- 添加/删除视图
// 添加视图
UIView *newView = [[UIView alloc] init];
[stackView addArrangedSubview:newView];// 从 StackView 中移除(不等于从父视图移除)
[stackView removeArrangedSubview:oldView];
[oldView removeFromSuperview]; // 若不需要了就彻底移除
- 嵌套使用StackView(可以将一个StackView作为另一个Stackview的arrangedSubView)
UIStackView *horizontalStack = [[UIStackView alloc] initWithArrangedSubviews:@[label1, label2]];
horizontalStack.axis = UILayoutConstraintAxisHorizontal;
horizontalStack.spacing = 8;UIStackView *verticalStack = [[UIStackView alloc] initWithArrangedSubviews:@[horizontalStack, button]];
verticalStack.axis = UILayoutConstraintAxisVertical;
- 带动画的视图增删
[UIView animateWithDuration:0.3 animations:^{[stackView removeArrangedSubview:viewToRemove];[viewToRemove removeFromSuperview];[stackView layoutIfNeeded];
}];
注意事项
1.arrangedSubViews是StackView自动管理的,不应该手动改变他们的位置或者大小
2.不要在StackView上直接添加约束控制子视图的位置
3.UIStackView本质是一个透明容器,如果想要设置背景色,可以添加一个UIView,使用insertSubView: atIndex:
4.setCustomSpacing:afterView::设置某个特定子视图之后的间距,会覆盖掉默认的spacing属性,不影响其他间距
5.arrangedSubViews是stackview用来排列子视图的子视图数组,也就是说:[stackView addArrangedSubview:label];等效于:[stackview addSubView:label]; [stackView.arrangedSubviews addObject:label];也就是说arrangedSubViews是subViews的子集,所以如果只是从arrangedSubViews移除子视图,那么仍然显示,知识不被stakView自动布局