Masonry几个妙用

哈喽,我是二西,我又来了,今天来记录下Masonry的几个妙用,希望能帮到你们
日常推歌,燃燃燃~
踏山河 music.163.com/#/song?id=1…

自适应拉伸布局

你们是否遇到过这样的布局,前面一张固定大小的图片,中间一个长短不固定昵称,后面有紧贴着昵称的小图标,然后最后还有一个靠右的固定大小图片。这种布局的难点在哪里呢?昵称如果短没啥问题,但是一旦昵称很长,后面的图标有可能就重叠,也有可能直接超出屏幕外面,是不是是不是。好了,我这里提供一个解决方案,如果有更好的方案欢迎评论区提出来~
上代码

//头像
UIImageView *headImageV = [[UIImageView alloc] init];
//昵称
UILabel *nicknameL = [[UILabel alloc] init];
//图标1
UIImageView *icon1V = [[UIImageView alloc] init];
//图标2
UIImageView *icon2V = [[UIImageView alloc] init];
//关注
UIButton *followBtn = [UIButton buttonWithType:UIButtonTypeCustom];

[self.view addSubview:headImageV];
[self.view addSubview:nicknameL];
[self.view addSubview:icon1V];
[self.view addSubview:icon2V];
[self.view addSubview:followBtn];

[headImageV mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.mas_equalTo(16);
    make.top.mas_equalTo(16);
    make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[nicknameL mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.mas_equalTo(headImageV.mas_right).mas_offset(10);
    make.top.mas_equalTo(20);
}];
[icon1V mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.mas_equalTo(nicknameL.mas_right).mas_offset(6);
    make.centerY.mas_equalTo(nicknameL);
    make.size.mas_equalTo(CGSizeMake(16, 16));
}];
[icon2V mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.mas_equalTo(icon1V.mas_right).mas_offset(6);
    make.centerY.mas_equalTo(nicknameL);;
    make.size.mas_equalTo(CGSizeMake(16, 16));
}];
[followBtn mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.mas_equalTo(icon2V.mas_right).mas_offset(10).priorityHigh();//重点1
    make.centerY.mas_equalTo(headImageV);
    make.right.mas_equalTo(16);
}];

//重点2
[headImageV setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[headImageV setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[nicknameL setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[nicknameL setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
[icon1V setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[icon1V setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[icon2V setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[icon2V setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[followBtn setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[followBtn setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
复制代码

重点1这里,要设置priorityHigh(),这个属性可以设置两个控件之间约束的优先级,解决约束冲突,可以使控件之间留有空白

重点2这里,有两个方法,setContentHuggingPriority(抗拉伸),setContentCompressionResistancePriority(抗压缩),这两个方法主要用途是这样的,比如,水平方向有两个控件,两个控件约束铺满水平,但是控件内容并没有达到,这时候,应该优先拉伸哪个控件呢,就是靠这个setContentHuggingPriority来判断,反之,如果两个控件内容加起来超过一行,这时候又要压缩哪个控件的内容呢,就是靠setContentCompressionResistancePriority来判断了。理解起来可能有点难,建议度娘谷哥食用哈哈哈

评论区新写法

感谢 @DTL432591:
重点1这里改为 make.left.mas_greaterThanOrEqualTo(icon2V.mas_right).mas_offset(10);
重点2只需设置nicknameL的抗压缩属性 [nicknameL setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
我试了下是可以实现的这种需求的,原理差不多,通过mas_greaterThanOrEqualTo产生一定空隙,再设置控件的抗压缩低优先级,防止过长时挤压其他控件。这代码理解起来可能比较容易,推荐大家尝试尝试,有问题我们在讨论讨论哈~

UIScrollView布局

用Masonry来布局UIScrollView,直接对scrollView进行约束是不行的,我这边的方案是通过一个中间view来充当容器,用这个容器大小来撑开scrollView,这个view的大小实际上就是contentSize。当然啦,依旧欢迎大家的方案,评论区见~

UIScrollView *scrollView = [[UIScrollView alloc] init];
UIView *contentV  = [[UIView alloc] init];
UIView *firstV  = [[UIView alloc] init];
UIView *secondV  = [[UIView alloc] init];

[scrollView addSubview:contentV];
[contentV addSubview:firstV];
[contentV addSubview:secondV];

[contentV mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(scrollView);
    make.height.mas_equalTo(100);
}];
[firstV mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.bottom.mas_equalTo(0);
    make.left.mas_equalTo(16);//内容左约束
    make.width.mas_equalTo(100);
}];
[secondV mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.bottom.mas_equalTo(0);
    make.left.mas_equalTo(firstV.mas_right).mas_offset(10);
    make.right.mas_equalTo(-16);//内容右约束
    make.width.mas_equalTo(100);
}];
复制代码

有个问题说下,这种方案实际上就是靠contentV上添加的view左右约束来撑开contentV,使contentV有宽度,scrollView就可以滑动啦。当然,你也可以直接给contentV设置一个width约束,这样也可以滑动

Masonry动画

Masonry改变约束支持动画

UIView *view = [[UIView alloc] init];
[self.view addSubview:view];

[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(100);
    make.left.right.mas_equalTo(0);
    make.height.mas_equalTo(50);
}];

//支持动画
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.3 animations:^{
    [view mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(400);
    }];
    [self.view layoutIfNeeded];
}];
复制代码

做动画一定要记得进行父控件layoutIfNeeded刷新下约束,不然没效果。而外说一句,这个方法可以马上刷新布局,得到控件frame数值

最后

暂时只能想到这几个,大家还有没有Masonry其他的特别用法,有的话欢迎评论区提出来啦啦啦~~~

猜你喜欢

转载自juejin.im/post/6924945470683316231
今日推荐