UIStackView布局

前言

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;
}

参考资料

Flex 布局教程
iOS开发高手课
iOS9新特性UIStackView

你可能感兴趣的:(UIStackView布局)