这几个方法其实在几个月前已经很想抽出一大段完整的时间去研究透了,可惜项目暂时木有碰上这几个方法,这几天好好整一整,想起知乎的一段有意思的话,国外程序员,碰到问题,打开google,看了看stackoverflow,解决问题,国内程序猿,碰到问题,打开百度,摇了摇头,翻墙,打开google,看了看stackoverflow,脑海翻译一遍,解决问题。这几天真的是深有体会!!碰到比较难点和纠结的问题,一定要看看国外的朋友们的解析,事半功倍啊!!
LayoutIfNeeded 这个方法也是UIView 和 CALayer都有的方法,我们这里不打算举对比例子,因为几乎的难点都是在 LayoutIfNeeded 和 setNeedsLayout两个方法的差别,先来看看官方文档:
立即更新subviews的布局,而记得吗?setNeedsLayout则是标志一个flag,等待下次更新循环的时候更新布局,如果我们写一个例子,只调用LayoutIfNeeded相信大家都能知道,不能调用LayoutSubViews,而需要先前用好了setNeedsLayout作一次标志。好了,问题来了,那究竟这有什么区别呢。。。
我也不懂哈哈。所以找到了这样的一个好文章:
http://stackoverflow.com/questions/2807137/what-is-the-relationship-between-uiviews-setneedslayout-layoutifneeded-and-lay
我们就用问题里面举的例子来解析吧!
假设我们自定义了一个视图,这个视图具备边框margin的变化的动画效果(在animate Block里面实现),我们在layoutSubViews方法里面变更:
- (void) layoutSubviews {
self.contentView.frame = CGRectMake(
self.bounds.origin.x + self.edgeInsets.left,
self.bounds.origin.y + self.edgeInsets.top,
self.bounds.size.width - self.edgeInsets.left - self.edgeInsets.right,
self.bounds.size.height - self.edgeInsets.top - self.edgeInsets.bottom);
}
并且重载setEdgeInset方法,旨在setEdgeInset同时调用layoutSubviews方法,如果我们只用了setNeedsLayout:
- (void) setEdgeInsets:(UIEdgeInsets)edgeInsets {
_edgeInsets = edgeInsets;
[self setNeedsLayout]; //Indicates that the view needs to be laid out
//at next update or at next call of layoutIfNeeded,
//whichever comes first
}
这时候如果想要有动画效果,所以放置在animate Block里面:
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
在animate Block结束的下次一个更新周期才变更哪些效果,所以并不能达到我们要的效果,那要怎么样呢?答案就是加上layoutIfNeeded方法
- (void) setEdgeInsets:(UIEdgeInsets)edgeInsets {
_edgeInsets = edgeInsets;
[self setNeedsLayout]; //Indicates that the view needs to be laid out
//at next update or at next call of layoutIfNeeded,
//whichever comes first
[self layoutIfNeeded]; //Calls layoutSubviews if flag is set
}
这里强化一下,next update cycle的概念,例如两个视图控制器A,B,正在显示A视图,如果B视图需要刷新绘图或者布局,那么,iOS基于优化的角度,不会马上更新B视图,而是在适当的时机更新B视图。
国内的一些朋友说了一大堆,要么就是直接转载别人,要么就是生硬翻译官方文档的,甚至还有说错了的。。。所以我们还是得多向别人学习学习!
参考:
http://stackoverflow.com/questions/2807137/what-is-the-relationship-between-uiviews-setneedslayout-layoutifneeded-and-lay