ios 离屏渲染和异步绘制,为什么要离屏渲染

  ios 离屏渲染和异步绘制,为什么要离屏渲染

  Python实战社群

  Java实战社群

  长按识别下方二维码,按需求添加

  扫码关注添加客服

  进Python社群

  扫码关注添加客服

  进Java社群

  作者丨收納箱

  来源丨掘金

  链接:

  https://juejin.im/post/5f0339505188252e817c6c02

  测试环境

  Xcode 11.4

  iPhone 11 Pro

  iOS 13.5

  1. 如何设置圆角才会触发离屏渲染我们经常看到,圆角会触发离屏渲染。但其实这个说法是不准确的,因为圆角触发离屏渲染也是有条件的!

  我们先来看看苹果官方文档对于拐角半径的描述:

  将半径设置为大于0.0的值会导致图层开始在其背景上绘制圆角。默认情况下,圆角半径不适用于图层内容属性中的图像;它仅适用于图层的背景色和边框。但是,将masksToBounds属性设置为真实的会导致内容被裁剪为圆角。

  我们发现设置拐角半径大于0时,只为层的背景颜色和边界设置圆角;而不会对层的内容设置圆角,除非同时设置了layer.masksToBounds为真(对应自定义的剪辑边界属性)。

  如果这时,你认为layer.masksToBounds或者剪辑边界设置为真实的就会触发离屏渲染,这是不完全正确的。

  我们先打开模拟器的离屏渲染颜色标记:

  不设置layer.masksToBounds或者clipsToBounds,其默认值为不

  -(void)viewDidLoad {[super viewDidLoad];ui view * view 1=[[ui view alloc]initWithFrame:CGRectMake(0,0,200.0,200.0)];//设置背景色观点1。背景色=用户界面颜色。红色;//设置边框宽度和颜色观点1。层。边框宽度=2.0;观点1。层。边框颜色=用户界面颜色。黑色。CG颜色;//设置圆角观点1。层。拐角半径=100.0;观点1。中心=自我。查看。居中;【自我。view addSubview:view 1];}

  我们看到只有背景色、边框以及圆角的时候,确实不会触发离屏渲染。

  设置layer.masksToBounds或者剪辑边界为是

  -(void)viewDidLoad {[super viewDidLoad];ui view * view 1=[[ui view alloc]initWithFrame:CGRectMake(0,0,200.0,200.0)];//设置背景色观点1。背景色=用户界面颜色。红色;//设置边框宽度和颜色观点1。层。边框宽度=2.0;观点1。层。边框颜色=用户界面颜色。黑色。CG颜色;//设置圆角观点1。层。拐角半径=100.0;//设置裁剪观点1。剪辑到边界=是;观点1。中心=自我。查看。居中;【自我。view addSubview:view 1];} 当我们开启layer.masksToBounds或者剪辑边界时,同样的没有触发离屏渲染。这是因为我们还没有设置图片。

  设置layer.masksToBounds或者剪辑边界为是的,同时设置图片

  -(void)viewDidLoad {[super viewDidLoad];ui view * view 1=[[ui view alloc]initWithFrame:CGRectMake(0,0,200.0,200.0)];//设置背景色观点1。背景色=用户界面颜色。红色;//设置边框宽度和颜色观点1。层。边框宽度=2.0;观点1。层。边框颜色=用户界面颜色。黑色。CG颜色;//设置图片观点1。层。contents=(_ _ bridge id)[ui image image name:@ pkq ].CGImage//设置圆角观点1。层。拐角半径=100.0;//设置裁剪观点1。剪辑到边界=是;观点1。中心=自我。查看。居中;【自我。view addSubview:view 1];} 当我们开启layer.masksToBounds或者剪辑边界时,同时设置图片时,就会触发离屏渲染。

  其实不光是图片,我们为视图添加一个有颜色、内容或边框等有图像信息的子视图也会触发离屏渲染。

  有图像信息还包括在视图或者层的画方法中进行绘制等。

  -(void)viewDidLoad {[super viewDidLoad];ui view * view 1=[[ui view alloc]initWithFrame:CGRectMake(0,0,200.0,200.0)];//设置背景色view 1 . background color=ui color . red color;//设置边框宽度和颜色view 1 . layer . border width=2.0;view 1 . layer . border color=ui color . black color . CG color;//设置圆角view 1 . layer . corner radius=100.0;//设置剪辑view1.clipsToBounds=YES//子视图ui view * view 2=[[ui view alloc]initwithframe:cgrectmake(0,0,100.0,100.0)];//以下三个属性中的任意一个//设置背景色view 2 . background color=ui color . blue color;//设置内容view 2 . layer . contents=(_ _ bridge id)([UI image named:@ pkq ]。cgimage);//设置边框view 2 . layer . border width=2.0;view 2 . layer . border color=ui color . black color . CG color;[视图1添加子视图:视图2];view 1 . center=self . view . center;[self . view addSubview:view 1];}

  2. 圆角触发离屏渲染的真正原因层的叠加图大概遵循“画家算法”。

  油画算法:先画场景中离观察者较远的物体,再画较近的物体。

  先画红色部分,再画彩色部分,最后画灰色部分,可以解决消隐面的问题。即根据物理距离和观察者的距离对场景进行排序,可以从远到近进行绘制。

  当为拐角裁剪设置cornerRadius和masksToBounds时,masksToBounds裁剪属性将应用于所有图层。

  我们以前是从后往前画,画完一层就可以丢弃了。但是现在需要依次保存在Offscreen Buffer,等待切圆角过程,也就是离屏渲染被触发。

  背景色,边框,背景色边框,加圆角切割。根据文档,masksToBounds设置为YES或NO并不重要,因为在contents = nil中没有任何内容需要删除。

  一旦我们做出为contents设置了内容,无论是图片,绘图内容,带图像信息的子视图等。加上圆角裁剪,会触发离屏渲染。

  不一定要直接给内容赋值!

  3. iOS9及以后的优化苹果对圆角、iOS 9及以后的系统版本做了一些优化。

  图层.内容/图像视图.图像

  我们只设置了contents或者UIImageView的图像,加上圆角,不会产生离屏渲染。但是,如果添加了背景色、边框或其他包含图像内容的图层,仍然会出现离屏渲染。

  -(void)viewDidLoad {[super viewDidLoad];ui view * view 1=[[ui view alloc]initWithFrame:CGRectMake(0,0,200.0,200.0)];//设置图片view 1 . layer . contents=(_ _ bridgeid)[ui image named:@ qiyu ]。cgimage//设置圆角view 1 . layer . corner radius=100.0;//设置剪辑view1.clipsToBounds=YESview 1 . center=self . view . center;[self . view addSubview:view 1];}

  其实这也是可以理解的,因为只有单层的内容需要进行圆角裁剪,所以不需要屏外渲染技术。但是,如果添加了背景色、边框或其他有图像内容的图层,多层会被四舍五入和裁剪,所以仍然会触发离屏渲染(比如1中的第三个例子)。

  所以,我们在使用类似UIButton的视图时需要注意:

  UIButton

  -(void)viewDidLoad {[super viewDidLoad];self . view . background color=[ui color white color];//创建按钮视图ui button * button=[[uibuttonalloc]initwithframe:cgrectmake(0,0,200.0,200.0)];//设置图片[Button SetImage:[UI Image Named:@ PKQ ]for state:UIControlStateNormal];button . center=self . view . center;[self . view addSubview:button];}

  当我们为UIButton设置图片时,实际上会添加一个UIImageView。

  向UIButton添加圆角和裁剪将触发离屏呈现。

  I//设置圆角button.layer.corner半径=100.0;//设置剪辑按钮. button.clipsToBounds=YES

  不会触发离屏渲染如果在UIButton中更改为UIImageView添加圆角和裁剪。

  //设置rounded button . imageview . layer . corner radius=100.0;//设置剪辑按钮. button.imageview.clipstobonds=yes复制代码

  要了解更多关于渲染问题的信息,您可以阅读下面的文章。

  iOS渲染原理分析

  作者储物盒

  链接 3359juejin.im/post/5f0339505188252e817c6c02

  程序员专栏扫码关注添加客服长按识别下方二维码进群

  近期精彩内容推荐:

  哈工大大四学生被开除,痛失知名大厂Offer

  有个程序员老公有多爽???

  碉堡了!一款专门为程序员的编程字体!

  助你进大厂,这些知识你是必须知道的。

  在看点这里好文分享给更多人

  如何在CSS中设置div滚动条的样式

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码:

Copyright @ 2018-2022 盛行IT 合作邮箱: mdzz19960812@outlook.com

备案号:湘ICP备2023015575号