• Masonry框架初次使用遇到的坑 frame为0


     

    实现自适应布局的一个非常方便的方法就是使用Masonry框架,然而使用Masonry布局的时候,并不能立刻反应到frame的改变上,比如:

    UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    UIImageView *child = [UIView alloc] init];
    [parent addSubview:child];
    [child mas_makeConstraints:^(MASConstraintMaker *make) {
            make.size.mas_equalTo(CGSizeMake(20,20));
            make.top.left.mas_equalTo(50);
        }];
    NSLog(@"%@",redView);
    
    打印结果:
    ** <UIImageView: 0x7fb222605550; frame = (0 0; 0 0); layer = <CALayer: 0x7fb22260b3a0>>**

    可以发现,虽然使用Masonry进行布局和约束,但是子视图childframe仍然为(0, 0, 0 ,0). 

    而这时候如果有需求要设置child的形状为圆形,就得知道它的frame,像下面这样写肯定不会设置成功的:

    [child mas_makeConstraints:^(MASConstraintMaker *make) {
            make.size.mas_equalTo(CGSizeMake(20,20));
            make.top.left.mas_equalTo(50);
        }];
     child.layer.cornerRadius = child.bounds.size.width/2;
     child.layer.masksToBounds = YES; //设置头像为圆形

    因为这时候的frame还是0。我想会不会是因为block中的处理是放在另一个线程中异步进行的,block还没执行完就已经走到了下面使用frame的代码,(一阵狂喜,好聪明。。。),所以马上把代码改写:

    [child mas_makeConstraints:^(MASConstraintMaker *make) {
            make.size.mas_equalTo(CGSizeMake(20,20));
            make.top.left.mas_equalTo(50);
            child.layer.cornerRadius = child.bounds.size.width/2;
            child.layer.masksToBounds = YES; //设置头像为圆形
        }];

    然而并没有什么卵用。。。

    没办法只能问谷歌了,然后找到了Masonry约束下获取frame的方法:

    使用masonry的实质还是调用了ios7以后的autolayout,如果要更新frame,需要调用layoutIfNeeded函数进行布局,然后所约束的控件才会按照约束条件,生成当前布局相应的framebounds。这样就可以利用这两个属性来进行图片圆角剪裁。而调用layoutIfNeeded的目的是让系统调用layoutSubviews方法,我们也可以直接在这个方法里获取frame,因为这时候开始layout subviews,Masonry已经计算出了真实的frame。

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

    setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。

    layoutIfNeeded:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点,动画可以在更新布局后直接使用这个方法让动画生效。

    layoutSubviews:系统重写布局

    setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始

    updateConstraintsIfNeeded:告知立刻更新约束

    updateConstraints:系统更新约束

  • 相关阅读:
    如何完全备份android在系统system分区和data分
    U3D游戏开发商思考
    安德鲁斯Toast它们的定义和防止重复显示器
    android反射组件 (一个)java 它们的定义annotation基础知识
    ZOJ 3794 Greedy Driver spfa
    [LeetCode OJ] Copy List with Random Pointer 扩大
    LAN公布java web项目的方法的外侧
    [RxJS] Creation operator: create()
    [RxJS] Creation operators: interval and timer
    [Unit Testing] Angular Test component with required
  • 原文地址:https://www.cnblogs.com/yecong/p/6876813.html
Copyright © 2020-2023  润新知