关于画圆角以及离屏渲染的问题

我们都知道cornerRadius + masksToBounds:适用于单个视图或视图不在列表上且量级较小的情况,会导致离屏渲染。

那么,什么是离屏渲染?

Off-Screen Rendering  离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。离屏渲染之所以会是帧数杀手,是因为离屏渲染需要在当前屏幕缓冲区以外创建一个新的缓冲区,并在渲染过程中需要多次切换上下文,首先将上下文环境从当前屏幕切换到离屏进行离屏渲染。渲染结束以后,需要将离屏渲染缓冲区的结果显示到屏幕上。然后再将上下文环境从离屏切换到当前屏幕。然而,上下文切换的代价是很大的,首先我要保存当前屏幕渲染环境,然后切换到一个新的绘制环境,申请绘制资源,初始化环境,然后开始一个绘制,绘制完毕后销毁这个绘制环境,如需要切换到On-Screen Rendering或者再开始一个新的离屏渲染重复之前的操作。

触发离屏渲染的操作有1、shouldRasterize(光栅化)(少用)2、masks(遮罩),cornerRadius属性设置虽不会触发离屏渲染,但是它仅对视图的背景和边界有效,对layer的contents不起作,所以UIImageView、UILabel、UIButton对象单纯设置cornerRadius无效,需要再加上masksToBounds = true,而这就会触发离屏渲染,但是如果你的圆角视图不多,cell 不复杂,就不要费力气折腾了,因为数量不多的圆角并不会引起掉帧,iOS9之后对UIImageView的圆角设置做了优化,UIImageView这样设置圆角不会触发离屏渲染,而UIButton还是都会触发离屏渲染。

其他设置圆角的方法有:1、使用贝塞尔曲线UIBezierPath和Core Graphics框架画出一个圆角,需要注意的是Core Graphics通过CPU重新绘制一份带圆角的视图来实现圆角效果,会大大增加CPU的负担,而且相当于多了一份视图拷贝会增加内存开销。但是就显示性能而言,由于没有触发离屏渲染,所以能保持较高帧率。

2、使用CAShapeLayer和UIBezierPath设置圆角,通过设置view.layer的mask属性,可以将另一个layer盖在view上,也可以设置圆角,但是mask同样会触发离屏渲染,但是对内存的消耗最少,而且渲染快速

3、如果是图片的话可考虑直接将图片切成圆角

posted @ 2020-03-24 15:48  小妮子的奋斗时代  阅读(284)  评论(0编辑  收藏  举报