iOS技术

关于masonry和frame布局的一些坑

2023-09-27  本文已影响0人  Wesson

记录几点最新开发过程中,使用masonry和frame布局时遇到的一些坑。

  1. masonry的底层也是autoLayout,本质也是根据约束,动态地计算出frame。 当同时使用masonry和frame时,设置的frame会被替代掉(注意是替换,而不是合并)
    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 112, 154)];
    [self.view addSubview:starImgView];
    [imgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.view).offset(-29);
        make.top.equalTo(self.view).offset(-77);
    }];

上面这段代码中,先用frame设置了imgView的宽和高。
然后使用masonry设置了坐标。 布局完之后,发现图形没有显示出来,imgView的宽高都是0.
原因就是使用masonry之后,会根据约束重新计算一个frame,而不会和原先的frame进行合并。

  1. masonry的底层是根据autoLayout,计算frame。将约束转换成frame需要时间,不是立即的。所以如果想要在设置好约束后,获取到此时的frame相关信息(如宽高,left,right),需要layoutIfNeeded。

  2. 对mas_makeConstraints、mas_updateConstraints、mas_remakeConstraints的区别


    image.png

    这里,所谓的“已有某类型约束”,是需要firstItem,secondItem,firstAttribute,secondAttribute,relation,multiplier,priority等一致才会当做同一个约束。以下为masonry判断是否为同类型约束的源码

- (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint {
    // check if any constraints are the same apart from the only mutable property constant

    // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints
    // and they are likely to be added first.
    for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) {
        if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue;
        if (existingConstraint.firstItem != layoutConstraint.firstItem) continue;
        if (existingConstraint.secondItem != layoutConstraint.secondItem) continue;
        if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue;
        if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue;
        if (existingConstraint.relation != layoutConstraint.relation) continue;
        if (existingConstraint.multiplier != layoutConstraint.multiplier) continue;
        if (existingConstraint.priority != layoutConstraint.priority) continue;

        return (id)existingConstraint;
    }
    return nil;
}
上一篇 下一篇

猜你喜欢

热点阅读