关于CALayer对Masonry使用的一个简单解决办法

在刚使用Masonry的时候,会碰到需要将单独的图层Layer添加到View上,而CALayer是不可以调用Masonry方法的,这对于在使用Masonry的情况就比较尴尬,下面我们来直接用一种比较简单的解决办法,后边会简单讲一下原因。

解决办法

我们可以通过获取View的frame来解决这一问题,而通过Masonry添加约束后是不会及时更新相对应的frame的。
这个时候我们可以通过layoutIfNeeded来调用layoutSubviews这个方法来解决,这么说可能有点蒙,举个例子看一下

- (void)updateFrames
{
    [self.view.layer insertSublayer:self.subLayer atIndex:0];
    [self.view layoutIfNeeded];
}

- (void)layoutSubviews{
    [super layoutSubviews];
    
    self.subLayer.frame = self.view.bounds;
}

这时我们看到当我们调用[self.view layoutIfNeeded]时,- (void)layoutSubviews方法被调用了,并且得到了约束后View的frame。
有的时候,会发现我们调用了layoutIfNeeded,但- (void)layoutSubviews方法却没有被调用,我们可以在调用layoutIfNeeded之前先调用一下setNeedsLayout

- (void)updateFrames
{
    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
}

- (void)layoutSubviews{
    [super layoutSubviews];
    
    self.subLayer.frame = self.view.bounds;
}

这样- (void)layoutSubviews方法一定会调用,下面来简单讲一下原因。

原因

Masonry是对Autolayout的一个封装,当通过Autolayout对控件添加约束后,系统会调用layoutSubviews来对所有VIew更新frame,但我们通过Masonry对View添加完约束后不是马上就会调用layoutSubviews方法。
这时我们就可以调用layoutIfNeeded和setNeedsLayout方法来对layoutSubviews方法进行调用。但为什么有时只需要调用layoutIfNeeded而有时还要现调用一下setNeedsLayout呢,下面简单讲一下这两个方法

  • layoutIfNeeded:
    如果有满足一下条件,就立刻更新布局。
  1. 有 addSubview 操作
  2. 设置了view的 frame,当然前提是设置前后 frame 的值发生了变化
  3. 滚动一个UIScrollView
  4. 旋转 Screen
  5. 改变一个UIView大小的时候
  • setNeedsLayout:
    标记页面需要更新,但是不一定什么时候才会调用
    layoutSubviews 去刷新布局。

如果我们不管什么时候都想强制调用layoutSubviews方法的话就同时调用

    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容