美文网首页UIKit
iOS-View绘制

iOS-View绘制

作者: JerrySi | 来源:发表于2019-07-30 10:15 被阅读0次

    关于渲染机制是很多开发人员容易忽略掉的,很多时候认为会用就可以了,其实知道底层渲染机制特别是渲染的时间点对我们是很有帮助的。

    这里有篇文章写的不错:https://blog.csdn.net/yangyangzhang1990/article/details/52452707/

    本文对该文章结合自己的经验进行结论整理。


    绘制流程

    当在操作 UI 时,比如改变了 Frame、更新了 UIView/CALayer 的层次时,或者手动调用了 UIView/CALayer 的 setNeedsLayout/setNeedsDisplay方法后,这个 UIView/CALayer 就被标记为待处理,并被提交到一个全局的容器去。

    苹果注册了一个 Observer 监听 BeforeWaiting(即将进入休眠) 和 Exit (即将退出Loop) 事件,回调去执行一个很长的函数:_ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv()。这个函数里会遍历所有待处理的 UIView/CAlayer 以执行实际的绘制和调整,并更新 UI 界面。


    drawRect什么时候会被调用?

    前提:如果UIView没有设置rect大小,将直接导致drawRect不被调用。

    1. setNeedsDisplay:需要重绘,异步调用drawRect

    2. - (void)setNeedsDisplayInRect:(CGRect)rect:需要局部重绘,同样会异步调用drawRect

    3. 通过设置view的contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect。

    4. 调用sizeThatFits会触发调用drawRect。

    drawRect性能优化原则:缩小绘制区域,降低重绘频率


    layoutSubviews什么时候会被调用?

    前提:如果UIView没有设置rect大小,将直接导致layoutSubviews不被调用。

    1.调用setNeedsLayout 或者 layoutIfNeeded的时候

    2.addSubview的时候。

    3.当view的size发生改变的时候。

    4.滑动UIScrollView的时候。

    5.旋转Screen会触发父UIView上的layoutSubviews事件。


    这里顺便说明下setNeedsLayout和layoutIfNeeded区别

    1. setNeedsLayout

    标记为需要重新布局,不立即刷新,但layoutSubviews一定会被调用,配合layoutIfNeeded立即更新

    2. layoutIfNeeded

    如果有需要刷新的标记,立即调用layoutSubviews进行布局

    3. 用法

    如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局。

    事实上我们主动调用这2个方法的时候不多,大多数情况是通过约束初始化控件后,要及时得到控件的大小的时候,主动调用下layoutIfNeeded。

    相关文章

      网友评论

        本文标题:iOS-View绘制

        本文链接:https://www.haomeiwen.com/subject/gyqgrctx.html