什么是离屏渲染
如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的frame buffer,作为像素数据存储区域,而这也是GPU存储渲染结果的地方。如果有时因为面临一些限制,无法把渲染结果直接写入frame buffer,而是先暂存在另外的内存区域,之后再写入frame buffer,那么这个过程被称之为离屏渲染。
离屏渲染运行实例demo
//1.按钮存在背景图片
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
btn1.frame = CGRectMake(100, 30, 100, 100);
btn1.layer.cornerRadius = 50;
[self.view addSubview:btn1];
[btn1 setImage:[UIImage imageNamed:@"btn.png"] forState:UIControlStateNormal];
btn1.clipsToBounds = YES;
//2.按钮不存在背景图片
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
btn2.frame = CGRectMake(100, 180, 100, 100);
btn2.layer.cornerRadius = 50;
btn2.layer.borderWidth = 10;
btn2.layer.borderColor = [[UIColor redColor] colorWithAlphaComponent:0.3].CGColor;
btn2.backgroundColor = [UIColor blueColor];
[self.view addSubview:btn2];
btn2.clipsToBounds = YES;
//3.UIImageView 设置了图片+背景色;
UIImageView *img1 = [[UIImageView alloc]init];
img1.frame = CGRectMake(100, 320, 100, 100);
img1.backgroundColor = [UIColor blueColor];
[self.view addSubview:img1];
img1.layer.cornerRadius = 50;
img1.layer.masksToBounds = YES;
img1.image = [UIImage imageNamed:@"btn.png"];
//4.UIImageView 只设置了图片,无背景色;
UIImageView *img2 = [[UIImageView alloc]init];
img2.frame = CGRectMake(100, 480, 100, 100);
[self.view addSubview:img2];
img2.layer.cornerRadius = 50;
img2.layer.masksToBounds = YES;
img2.image = [UIImage imageNamed:@"btn.png"];
结果
Why?
先来了解下CALayer的结构
CALayer结构
图层叠加绘制遵循 油画算法 ,按次序输出到frame buffer,后一层覆盖前一层,就能得到最终的显示结果(渲染完成后丢弃不做保存)。
如果想对绘制好的结果界面进行圆角操作,是不可能的。要想实现圆角效果,只能把需要处理的Layer依次在 Offscreen Buffer处理,处理完成之后再写入frame buffer进行渲染。
Demo 解读
-
bt1
button设置背景图片进行圆角操作。
我们可以看下层级 UIButton中包含UIImageView层级,做圆角操作是需要离屏渲染的。
bt1层级
如果bt1 做下列修改则不会造成离屏渲染 与 img2是一个道理
btn1.imageView.layer.cornerRadius = 50;
btn1.imageView.clipsToBounds = YES;
-
bt2
设置了背景色和cornerRadius ,只为layer的backgroundColor和border设置圆角(content层不会被修改),设置clipsToBounds =YES后,会应用到所有图层,但是content层没有内容,所以不会触发离屏渲染。 -
img1
设置了Layer的backgroundColor层和content层,会触发离屏渲染。
总结
条件 (layer.clipsToBounds=YES && layer.cornerRadius>0)
1.当存在子layer(layer不透明)设置时触发离屏渲染。
2.单层layer设置 (backgroundColor && border),不设置content层不会触发离屏渲染,但是((backgroundColor || border)&&content )会触发离屏渲染。
网友评论