视图刷新是常有的事情,数据的更新、视图的创建、添加、滚动、frame的改变,都更刷新相关,掌握刷新的窍门,能提高应用的性能和用户体验。
layoutSubviews
以下几个动作都会触发layoutSubviews
- 1、创建视图
- 使用
initWithFrame
进行初始化时会触发layoutSubviews
,init
初始化不会触发 - 当
rect = CGRectZero
时,initWithFrame
也不会触发layoutSubviews
- 使用
- 2、添加视图: 使用
addSubview
方法 - 3、修改视图frame:设置view的Frame,并且frame的值设置前后不一样,会触发父UIView上的
layoutSubviews
事件 - 4、滚动视图:
UIScrollView
滚动的时候会调用更新视图 - 5、旋转屏幕:会触发父UIView上的
layoutSubviews
事件
看看 Apple 给出的描述:
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 thelayoutIfNeeded
method.
翻译成白话文,就是要重写layoutSubviews
这个方法,但是不要直接调用,而是用setNeedsLayout
来触发它执行刷新方法,但是这个方法并不会立即刷新,而是在下一次运行循环的时候才执行。若要立即更新,补上layoutIfNeeded
方法就OK啦
sizeToFit和 sizeThatFits:
sizeToFit
刷新调用者,给调用者一个最合适的size,这个size会紧紧的围绕着这个视图,例如:label调用它,那么label的size将会是最合适
的size:刚好容纳下所有文字(注:如果label设置了numberOfLines:
,那么只会给出对应的行数的size而不是全部)
sizeThatFits:
不会刷新调用者的frame,但是会返回最合适
的size(最合适
的意思同上)
具体用法见。。。
drawRect:和setNeedsDisplay
drawRect:提供绘制功能,如果要刷新绘画,不能直接调用,而是通过setNeedsDisplay来触发
setNeedsLayout:
。他会标记为需要重新布局,异步调用layoutIfNeeded
刷新布局,不立即刷新,但layoutSubviews
一定会被调用
setNeedsDisplayInRect:(CGRect)invalidRect:
- 标记为需要局部重绘sizeToFit会自动调用sizeThatFits方法
-
sizeToFit
不应该在子类中被重写,应该重写sizeThatFits
,sizeThatFits
传入的参数是receiver当前的size,返回一个适合的sizesizeToFit可以被手动直接调用sizeToFit和sizeThatFits方法都没有递归,对subviews也不负责,只负责自己
layoutSubviewslayoutIfNeeded
- 方法如其名,UIKit会判断该receiver是否需要layout.
根据Apple官方文档layoutIfNeeded方法应该是这样的:
- layoutIfNeeded遍历的不是superview链,而是subviews链
- drawRect是对receiver的重绘,能获得contextsetNeedDisplay在receiver标上一个需要被重新绘图的标记,在下一个draw周期自动重绘
- iphone device的刷新频率是60hz,也就是1/60秒后重绘
网友评论