zoukankan      html  css  js  c++  java
  • 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:系统更新约束

  • 相关阅读:
    Java中的final关键字解析
    twaver html5 如何设置节点不可拖动
    Redis Cluster 强制kill某一个节点和shutdown某一个节点后修复过程
    Redis Cluster 4.0.9 集群安装搭建
    Redis Cluster 获取主从关系
    Linux 只复制目录,不复制目录下数据文件
    安装redis cluster时:undefined method `invoke_with_build_args' for nil:NilClass
    redis : Can't save in background: fork: Cannot allocate memory
    MySQL 5.6 GTID 原理以及使用
    pt-query-digest使用详解
  • 原文地址:https://www.cnblogs.com/yecong/p/6876813.html
Copyright © 2011-2022 走看看