在刚使用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:
如果有满足一下条件,就立刻更新布局。
- 有 addSubview 操作
- 设置了view的 frame,当然前提是设置前后 frame 的值发生了变化
- 滚动一个UIScrollView
- 旋转 Screen
- 改变一个UIView大小的时候
- setNeedsLayout:
标记页面需要更新,但是不一定什么时候才会调用
layoutSubviews 去刷新布局。
如果我们不管什么时候都想强制调用layoutSubviews方法的话就同时调用
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
网友评论