前言
UIStackView是iOS9引入的用于線性布局的控件,自動管理嵌入其中的子視圖的布局。其原理主要是借鑒了前端的布局算法Flexbox,可以簡便、完整、響應式地實現各種頁面布局。
與自動布局相比,Flexbox提供了更多、更規范的布局方法,布局方式考慮地更全面,使用起來也更加方便。
Flexbox是Flexible Box的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。Flexbox 算法的主要思想是:讓 flex 容器能夠改變其flex項目的寬高和順序,以填充可用空間;flex容器可以通過擴大項目來填充可用空間,或者縮小項目以防止其超出其可用空間。Flex 布局教程
UIStackView布局示例
之前在項目中遇到過雙列表布局,如下圖所示。其中困難的地方在于有些項的內容行數不是固定的,但是又要求左右項不能錯亂,即左右對應項要上下對齊。
image.png
用Masonry能實現這個需求,但是感覺代碼就不那么簡潔,下面嘗試用UIStackView實現該布局。
// 雙列列表展示
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
[self layoutStackView];
}
// 布局:大stackView里包含3個縱向分布的小stackView;每個小stackView包含左右兩個label
- (void)layoutStackView {
UIStackView *stackView = [self stackViewWithAxis:(UILayoutConstraintAxisVertical) alignment:(UIStackViewAlignmentFill) distribution:(UIStackViewDistributionFill)];
[self.view addSubview:stackView];
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_offset(0);
make.left.mas_offset(10.0);
make.right.mas_offset(-10.0);
}];
for (int i = 0; i < 3; i++) {
UIStackView *rowStack = [self stackViewForRowAtIndex:i];
[stackView addArrangedSubview:rowStack];
};
}
// 創建每行stackView
- (UIStackView *)stackViewForRowAtIndex:(int)index {
UIStackView *stackView = [self stackViewWithAxis:UILayoutConstraintAxisHorizontal alignment:UIStackViewAlignmentFill distribution:UIStackViewDistributionFill];
stackView.spacing = 10.0;
NSDictionary *dict = @{@"00.姓名":@"清香白蓮素還真",@"01.詩號":@"半神半圣亦半仙,全儒全道是全賢,腦中真書藏萬卷,掌握文武半邊天。",@"02.武林地位":@"中原正道領袖"};
NSString *key = dict.allKeys[index];
for (int i = 0; i < 2; i++) {
UILabel *label = [self createLabel];
label.text = i == 0 ? key : dict[key];
[stackView addArrangedSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_greaterThanOrEqualTo(50.0);
}];
};
return stackView;
}
// 創建stackView
- (UIStackView *)stackViewWithAxis:(UILayoutConstraintAxis)axis alignment:(UIStackViewAlignment)alignment distribution:(UIStackViewDistribution)distribution {
UIStackView *stackView = [[UIStackView alloc]init];
stackView.axis = axis;
stackView.alignment = alignment;
stackView.distribution = distribution;
return stackView;
}
// 創建label
- (UILabel *)createLabel {
UILabel *label = [[UILabel alloc]init];
label.textColor = [UIColor blackColor];
label.numberOfLines = 0;
label.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0];
return label;
}