Masonry的约束布局,scrollView与cell的自动适配

公司项目使用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出来的表单就是可以是自动算高的了。

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

当然,对于表单结构,也可设置其压缩拉伸优先级达到效果:

    // 禁止拉伸优先级
    [self.numLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
    // 禁止压缩优先级
    [self.numLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];

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

end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值