关于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];

你可能感兴趣的:(关于CALayer对Masonry使用的一个简单解决办法)