下面列出View的layout的方法:
layoutSubviews
layoutIfNeeded
setNeedsLayout
setNeedsDisplay
drawRect
sizeThatFits
sizeToFit
我们这里抽取常用的几个进行验证学习
-
1、layoutSubviews
-- layoutSubviews在何时会被调用呢??
下面是苹果大大告诉我的 我也这么告诉你:
Discussion
The default implementation of this method does nothing on iOS 5.1 and earlier. Otherwise, the default implementation uses any constraints you have set to determine the size and position of any subviews.
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.
这个方法,默认没有做任何事情,需要子类进行重写 。 系统在很多时候会去调用这个方法,初始化不会触发layoutSubviews,但是如果设置了不为CGRectZero的frame的时候就会触发。
1.直接调用[self setNeedsLayout];(这个在上面苹果官方文档里有说明)
2.addSubview的时候。
3.当view的size发生改变的时候,前提是frame的值设置前后发生了变化。
4.滑动UIScrollView的时候。
5.旋转Screen会触发父UIView上的layoutSubviews事件(这个我验证了一下 确实没有触发layoutSubviews方法,查了很多资料都说会触发,大家自己定夺)。
下面来验证一下分析分析:
自定义一个DLView继承自UIView
@implementation DLView
- (void)layoutSubviews {
NSLog(@"来了");
}
初始化的时候不设置frame,直接addSubView会调用一次,如图:
初始化的时候设置frame为Zero
,然后addSubView会调用两次,如图:
初始化的时候设置frame,然后addSubView会调用两次,如图:
页面上创建一个button 点击改变view的frame,点击一次后 只要frame跟原来的frame有变化 就会调用一次layoutSubviews,再次点击就不会调用了,除非再次改变frame不一样的值:
补充:当我们自定义view的时候重写UIView的layoutSubviews如果程序需要对该控件所包含的子控件布局进行更精确的控制可通过重写该方法来实现。
-
2、layoutIfNeeded
也就是使用约束的时候 调一下可以立即更新效果
setNeedsLayout方法并不会立即刷新,立即刷新需要调用layoutIfNeeded方法!
苹果又告诉了我:
Before displaying a window that uses constraints-based layout the system invokes this method to ensure that the layout of all views is up to date. This method updates the layout if needed, first invoking updateConstraintsIfNeeded to ensure that all constraints are up to date. This method is called automatically by the system, but may be invoked manually if you need to examine the most up to date layout.
Subclasses should not override this method
翻译:
在显示使用基于约束的布局的窗口之前,系统调用此方法以确保所有视图的布局是最新的。这种方法更新布局,如果需要的话,首先调用updateconstraintsifneeded确保所有的约束都是最新的。该方法由系统自动调用,但如果需要检查最新的布局,则可以手动调用该方法。
子类不应覆盖此方法。
3、setNeedsDisplay
与setNeedsLayout方法相似的方法是setNeedsDisplay方法。该方法在调用时,会自动调用drawRect方法。drawRect方法主要用来画图。所以,当需要刷新布局时,用setNeedsLayOut方法;当需要重新绘画时,调用setNeedsDisplay方法。4、sizeThatFits、sizeToFit
一般在使用UILabel的时候会用到,使用这两个方法之前,必须要给label赋值,否则不会显示内容的。
[testLabel sizeThatFits:CGSizeMake(20, 20)];//会计算出最优的 size 但是不会改变 自己的 size,个人认为这个就是 label 自适应大小有用别的没什么用
[testLabel sizeToFit];//会计算出最优的 size 而且会改变自己的size