iOS中layout方法布局大解析

在iOS的UI层,有大量的以layout开头的方法,这里简单的总结一下每个layout的用法和时机

- (CGSize)sizeThatFits:(CGSize)size

- (void)sizeToFit

- (void)layoutSubviews

- (void)layoutIfNeeded

- (void)setNeedsLayout

- (void)setNeedsDisplay

- (void)drawRect:(CGRect)rect

在layoutSubviews中完成最终的布局,那么在什么时候调用呢?

1、init初始化不会触发layoutSubviews,但是用initWithFrame进行初始化的时候,当rect的值不是CGRectZero时也会触发

[[UIView alloc]initWithFrame:CGRectZero] 不会触发layoutSubviews

2、addSubview会触发layoutSubviews

3、设置view的frame的时候会触发,前提是前后的frame发生了变化。也就是说第一次设置的时候是init而不是initwith准确的说是view的size发生了变化。

4、滚动一个UIScrollView会触发

5、旋转screen会触发父UIView上的layoutSubviews事件

6、改变一个UIView大小的时候也会触发父View上的layoutSubviews;

这些事件的发生都是先父试图进行layoutSubviews,完成后再子试图调用,在试图第一次显示之前会统一调用一次layoutsubviews,但之前已经调用过的不会再调用,layoutSubviews默认系统自动调用,如果想要在这个方法里布局需要重写,但不能忘记 [super   layoutSubViews]; 

刷新布局

setNeedLayout会标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不会立即刷新,但是layoutSubviews一定会被调用,如果有刷新标记,立即调用layoutSubviews布局,如果需要立即刷新,首先调用setNeedsLayout,标记为立即刷新,然后马上调用  layoutIfNeeded  实现布局,在视图第一次显示之前,标记为总是需要刷新的,可以直接调用  layoutIfNeed

重绘

- (void)drawRect:(CGRect)rect 在它进行视图绘制,此方法一般是系统调用,若是想手动调用重新绘制使用 setNeedslayout方法标记,异步调用drawRect,局部绘制调用setNeedsDisplayInRect 方法标记为需要局部重绘

sizeToFit

sizeToFit会自动调用sizeThatFits方法

sizeToFit不应该在子类中被重写,应该重写sizeToFits

sizeToFits传入的参数是reveiver当前的size,返回一个适合的size

sizeToFit可以被手动直接调用

二者都没有递归,对subViews也不负责,只管自己

在视图第一次显示之前会调用一次,除非手动setNeedsDisplay或者UIView的属性设置为UIViewContentModeRedraw,否则任意改变布局不会重绘

layoutSubviews 系统执行过程

layoutSubviews方法先于drawRect;setNeedsLayout在receiver标记一个需要被重新布局的标记,在runloop的下一个周期自动调用layoutSubviews,UIKit会判断该receiver是否需要layout,setNeedsLayout会标记需要重新布局,下一个drawRect会自动重绘,iPhone的刷新频率是60,也就是1/60s后重绘

 

你可能感兴趣的:(UI)