Masonry+SDLayout+Frame 干货
2017-09-16 本文已影响158人
一直在路上66
Masonry基本使用与注意点
-
setNeedsLayout
:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。 -
layoutIfNeeded
:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。
布局包含label问题,先赋值,在比较bottom 重置或者更新约束即可
_nameLabel.text = [NSString stringWithFormat:@"%@ %@",model.nickname,model.end_mobile];
[_contentView setNeedsLayout];
[_contentView layoutIfNeeded];
if (self.navBtn.bottom>_nameLabel.bottom) {
[_contentView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
make.width.equalTo(self);
// make.height.mas_equalTo(@(HEIGHT - 64));
make.height.equalTo(self);//此处保证容器View高度的动态变化 大于等于0.f的高度
make.bottom.equalTo(self.navBtn.mas_bottom).offset(5);//
}];
}else{
[_contentView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
make.width.equalTo(self);
// make.height.mas_equalTo(@(HEIGHT - 64));
make.height.equalTo(self);//此处保证容器View高度的动态变化 大于等于0.f的高度
make.bottom.equalTo(_nameLabel.mas_bottom).offset(5);//
}];
}
-
layoutSubviews
:系统重写布局 -
setNeedsUpdateConstraints
:告知需要更新约束,但是不会立刻开始 -
updateConstraintsIfNeeded
:告知立刻更新约束 -
updateConstraints
:系统更新约束
Masonry自定义自适应高度View
自定义 SLDAdressMiddleView
UIView * contentView = [[UIView alloc] init];
[self addSubview:contentView];
_contentView = contentView;
[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
make.width.equalTo(self);
// make.height.mas_equalTo(@(HEIGHT - 64));
make.height.equalTo(self);//此处保证容器View高度的动态变化 大于等于0.f的高度
}];
[_contentView setNeedsLayout];
[_contentView layoutIfNeeded];
if (self.navBtn.bottom>_nameLabel.bottom) {
[_contentView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
make.width.equalTo(self);
// make.height.mas_equalTo(@(HEIGHT - 64));
make.height.equalTo(self);//此处保证容器View高度的动态变化 大于等于0.f的高度
make.bottom.equalTo(self.navBtn.mas_bottom).offset(5);//
}];
}else{
[_contentView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
make.width.equalTo(self);
// make.height.mas_equalTo(@(HEIGHT - 64));
make.height.equalTo(self);//此处保证容器View高度的动态变化 大于等于0.f的高度
make.bottom.equalTo(_nameLabel.mas_bottom).offset(5);//
}];
}
_contentView 是整个填充这个自定义SLDAdressMiddleView
注意在赋值数据 一定确定内部控件底部与_contentView底部的约束
- 当用到SLDAdressMiddleView
SLDAdressMiddleView *endAdressView = [[SLDAdressMiddleView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, 50)]; // 先给个假设frame 不给frame约束出错 50乱写的
[_contentView addSubview:endAdressView];
// 这是约束就不要约束高度了 会自适应高度
[endAdressView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_contentView.mas_left).offset(0);
make.top.equalTo(line3.mas_bottom).offset(0);
make.width.equalTo(_contentView);
}];
用Masonry布局ScrollerView
- 注意scrollView不需要设置contentSize 用一个_contentView填充scrollerView即可
[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_scrollView);
make.width.equalTo(_scrollView);
make.height.greaterThanOrEqualTo(@0.f);//此处保证容器View高度的动态变化 大于等于0.f的高度
}];
[_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_timeLabel.mas_bottom).offset(20.f);
make.left.equalTo(_contentView).offset(10);
make.right.equalTo(_contentView).offset(-10);
make.bottom.equalTo(_contentView).offset(-10);// 设置与容器View底部高度固定,contentLabel高度变化的时候,由于设置了容器View的高度动态变化,底部距离固定。 此时contentView的高度变化之后,ScrollView的contentSize就发生了变化,适配文字内容,滑动查看超出屏幕文字。
// make.height.greaterThanOrEqualTo(@16.f);//高度动态变化 大于等于16
}];
注意 一定确定底部控件与_contentView.mas_bottom 的约束
Masonry和FDTemplateLayoutCell搭配
- FDTemplateLayoutCell 在开发中对计算高度 cell动态变化提供了极大方便
- 计算Cell高度非常简单仅需要heightForRowAtIndexPath中的一行代码。不用再手动计算高度,基本用这个可以轻松搞定所有cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [tableView fd_heightForCellWithIdentifier:kYLLayoutTableViewCell cacheByIndexPath:indexPath configuration:^(YLLayoutTableViewCell *cell) {
[cell setFeed:[self.viewModel.feedArray objectAtIndex:indexPath.row]];
}];
}
可能会踩的坑,注意点
- 指定最下面view的bottom约束,这样才能够确切的计算出Cell的高度。
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.equalTo(self.iconView.leading);
make.top.equalTo(self.iconView.bottom).with.offset(10);
make.trailing.equalTo(-10);
make.bottom.equalTo(-10); //重要
}];
- Cell的subView要添加到contentView上,否则无法计算出准确的高度
添加subView时需要是:
[self.contentView addSubview:_contentLabel];
而不是:
[self.view addSubview:_contentLabel];
- Cell需要使用tableView的registerNib或者registerClass的方法进行注册,否则会报异常。
[self.tableView registerClass:[YLLayoutTableViewCell class] forCellReuseIdentifier:kYLLayoutTableViewCell];
- masonry+FDTemplateLayoutCell 文字高度计算(frame计算有时不准,需求变化改起来也比较痛苦,masonry只要修改里面的约束就可以了) 和cell高度问题