【iOS学习笔记 15-12-3】关于masonry布局中的frame和bounds

iPhone每年更新一款新的产品,屏幕也开始出现碎片化问题。所以在iPhone开发上面也碰到了和安卓一样不可避免的问题,就是不同屏幕的适配。

这些在面试中,也有面试官问到过,之前一直在忙着找工作的事,虽然autolayout出来了很久,但是一直没时间去研究。因为自己入门的时候就是学的代码布局,包括storyboard、xib用的比较少。

其实我现在代码布局要适配4,4s,5,6,6p感觉已经是强弩之末了,如果再出7的话真的要头疼了。而且我的步伐慢了,好多同行前辈都已经把autolayout研究的烂熟了,所以最近下决心要学一下autolayout,直接上手masonry。由于简书上面有很多比较好的教程,直接站在巨人的肩膀上研究这个。

感觉和之前使用的代码布局比较相似,于是很顺利的把项目中的一个界面换成了masonry布局。

但是在转换的过程中,发现UIView设置圆角的时候出现问题了,原始代码如下,img在APP中不显示。后来把贝塞尔曲线那一段注释掉,发现图片可以显示了,但是左上角和右上角的圆角没了。

//        UIImageView *img = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, imgwidth, imgheight)];
        UIImageView *img = [UIImageView new];
        [view addSubview:img];
        [img mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(0);
            make.left.mas_equalTo(0);
            make.width.mas_equalTo(imgwidth);
            make.height.mas_equalTo(imgheight);
        }];
        NSString *imgStr = [NSString stringWithFormat:@"http://www.baidu.com%@",[dic objectForKey:@"coverImage"]];//此处url是随便的一个网址
        NSURL *url = [NSURL URLWithString:imgStr];
        [img sd_setImageWithURL:url placeholderImage:nil];
        
        img.backgroundColor = [UIColor redColor];
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:img.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(5, 5)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = CGRectMake(0, 0, imgwidth, imgheight);
        maskLayer.path = maskPath.CGPath;
        img.layer.mask = maskLayer;
在网上查了很多资料,但是很少有介绍为什么在使用masonry之后控件的frame和bounds都是为0

后来翻倒一篇文章,才发现,其实对于masonry的理解不够深http://www.cocoachina.com/ios/20141010/9869.html

其实我还是没有摆脱传统代码里面的frame的影响,基于autolayout的masonry控制的空间布局不再取决于手动直接修改,而且是通过在storyboard或者code中提供的约束条件,通过一个自动布局引擎来实现的(见链接文章)。

当设置完控件的约束,需要调用layoutIfNeeded 函数进行布局,然后所约束的控件才会按照约束条件,生成当前布局相应的frame和bounds。这样就可以利用这两个属性来进行图片圆角剪裁。


下面附上关于autolayout更新几个方法的区别:

  • setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。
  • layoutIfNeeded:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。
  • layoutSubviews:系统重写布局
  • setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始
  • updateConstraintsIfNeeded:告知立刻更新约束
  • updateConstraints:系统更新约束
具体细节可以参考:

AutoLayOut框架Masonry使用心得



你可能感兴趣的:(【iOS学习笔记 15-12-3】关于masonry布局中的frame和bounds)