Masonry的约束布局,scrollView与cell的自动算高

来源:互联网 发布:python 写入环境变量 编辑:程序博客网 时间:2024/06/01 09:51

公司项目使用Masonry已经很久了,上一篇中介绍了约束的原生api和Masonry的一些基础用法,还对Label等控件的自带宽高问题进行了说明。今天我写一篇实用的关于scrollView的约束布局与cell的自动算高用法。

gitHub:https://github.com/yangqingren/LBMasonry.git

我们在使用约束布局的时候,子view通常可以决定自己的size,父view是可以不参与自子view的size布局的。比如:

@interface LBView ()@property (nonatomic,strong)UIView *subView;@end@implementation LBView- (instancetype)init {    if (self = [super init]) {        [self addSubview:self.subView];        [self.subView mas_makeConstraints:^(MASConstraintMaker *make) {            make.top.left.right.mas_equalTo(self);  // make. edges            make.height.mas_equalTo(100);            make.bottom.mas_equalTo(self.mas_bottom);        }];    }    return self;}@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    [self.view addSubview:self.lbView];    [self.view addSubview:self.lbLabel];    // self.lbView的size已经内部设置,所以不需要再次设置    [self.lbView mas_makeConstraints:^(MASConstraintMaker *make) {        make.top.left.offset(50);        make.right.offset(-50);    }];    // 验证self.lbView已经存在size    [self.lbLabel mas_makeConstraints:^(MASConstraintMaker *make) {        make.left.right.mas_equalTo(self.lbView);        make.top.mas_equalTo(self.lbView.mas_bottom).offset(10);    }];    // Do any additional setup after loading the view, typically from a nib.}
// 注:Masonry的block没有被self(即调用的view)持有,所以并不需要进行weakSelf- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {    self.translatesAutoresizingMaskIntoConstraints = NO;    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];    block(constraintMaker);    return [constraintMaker install];}// 我们自己做组件的时候也可以参考一下,做到这种效果

以上面的常见用法,引出了我在约束布局之路上的两个特殊例子:

  • scrollView的约束布局

使用scrollView的时候不需要去计算其contentSize,由其子view来进行约束设置。如果你还在使用scrollView的时候设置其contentSize,直接的话的讲,就是在写死布局。
如以上例子,当约束在水平(竖直)方向是满足两个条件,即足够完成布局,比如left+width(或者left+right或者right+width)。
但是当view的父类是scrollView时,则水平和竖直方向上都需要设置满3个条件,才能完成布局,例如:

- (UIScrollView *)scrollView {    if (!_scrollView) {    // 不需要设置contentSize        _scrollView = [[UIScrollView alloc] init];    }    return _scrollView;}
- (void)viewDidLoad {    [super viewDidLoad];    [self.view addSubview:self.scrollView];    [self.scrollView addSubview:self.view1];    [self.scrollView addSubview:self.view2];    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {        make.edges.mas_equalTo(self.view);    }];    // 加上width约束scrollView的contentSize的width,让scrollView在水平方向上能够撑开    [self.view1 mas_makeConstraints:^(MASConstraintMaker *make) {        make.top.left.right.mas_equalTo(self.scrollView);        make.height.mas_equalTo(500);        make.width.mas_equalTo(self.view.bounds.size.width);    }];    // 加上bottom连接scrollView的底部,加上两个view的高,让scrollView在竖直方向上能够撑开    [self.view2 mas_makeConstraints:^(MASConstraintMaker *make) {        make.top.mas_equalTo(self.view1.mas_bottom).offset(10);        make.left.right.mas_equalTo(self.scrollView);        make.height.mas_equalTo(500);        make.bottom.mas_equalTo(self.scrollView.mas_bottom).offset(-10);    }];    // Do any additional setup after loading the view, typically from a nib.}

约束布局不需要去计算scrollView的contentSize,让代码更加易于维护。

  • cell的自动算高

凡是能够使用scrollView布局的页面,tableView都能完成,比如一些表单页面,用tableView做就很方便数据的填充:

这里写图片描述

在做表单的时候,需要对不同cell进行不同的高度设置,有了cell的自动算高,这项工作就很轻松了。

首先需要给表单设置一个大约cell高度,以及设置cell的自动布局:

_tableView.estimatedRowHeight = 200;_tableView.rowHeight = UITableViewAutomaticDimension;// 或者是个别cell不需要自动算高- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {    if (0 == indexPath.section && 0 == indexPath.row) {        return 150;    }    return UITableViewAutomaticDimension;}

之后在cell里面对其的高度进行有效设置(水平方向不需要设置,cell的宽度默认为tableView的宽度):

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {-     if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {        [self addSubview:self.textField];        // 满足竖直方向上能够表达出cell的size的约束        [self.textField mas_makeConstraints:^(MASConstraintMaker *make) {            make.height.mas_equalTo(90);            make.edges.insets(UIEdgeInsetsMake(5, 15, 5, 15));        }];    }    return self;}

这样building出来的表单就是可以是自动算高的了。

至此,约束布局之路基本完成,可能在之后还会写一些关于约束的更特别的用法。

gitHub:https://github.com/yangqingren/LBMasonry.git

end