IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> [iOS开发]离屏渲染优化方案 -> 正文阅读

[移动开发][iOS开发]离屏渲染优化方案

阴影

laver本身是一块矩形区域,而阴影是作用于在整个非透明区域,并显示在所有layer的最下方。
根据画家算法,由远及近的渲染,阴影将会是是第一个被渲染的,但是阴影渲染有一个前提:我们必须已经画好了所有的layer和子layer
所以这时我们就需要一个临时缓存,这个缓存区就是离屏缓冲区,用来将所有layer都渲染完成,再根据所有layer和子layer组合后的图层的形状,添加阴影到FrameBuffer,最后显示到屏幕上。

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:@"111.jpg"];
imageView.center = CGPointMake(self.view.frame.size.width / 2, 200);
[self.view addSubview:imageView];
imageView.layer.shadowColor = UIColor.lightGrayColor.CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
imageView.layer.shadowOffset = CGSizeMake(5, 5);

离屏渲染:
请添加图片描述

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:@"111.jpg"];
imageView.center = CGPointMake(self.view.frame.size.width / 2, 200);
[self.view addSubview:imageView];
imageView.layer.shadowColor = UIColor.lightGrayColor.CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
//imageView.layer.shadowOffset = CGSizeMake(5, 5);
imageView.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(5, 5, imageView.frame.size.width, imageView.frame.size.height)].CGPath;

改成这样,就相当于知道了位置,可以先画阴影了:
请添加图片描述
此外还可以直接添加一个阴影图层或者使用Core Graphics绘制阴影。

需要裁剪的layer

这种场景就包含我们常用的圆角处理和clipsToBounds的处理。

注意:iOS官方针对UlImageView有一些优化:在iOS9之前,UllmageViewUIButton通过cornerRadius+masksToBounds 设置圆角都会触发离屏渲染,但是UImageView在iOS9以后,针对UIImageView中的image设置圆角并不会触发离屏渲染,如果加上了背景色或者阴影等其他效果还是会触发离屏渲染的。

这个的优化方案前面提过了。

使用了mask的layer

layer.mask
  • mask是覆盖在所有layer及其子layer之上的,可能还带有一定的透明度。
  • mask也是需要等整个layer树绘制完成,再加上mask和组合后的layer进行组合,所以需要开辟一个独立于FrameBuffer的内存,用于将layer及其子layer画完,最后再和mask进行组合,存储到FrameBuffer,视频控制器从FrameBuffer中读取数据显示到屏幕上。

优化方案:
不使用mask,使用混合图层,在layer上方叠加相应mask形状的半透明layer

设置了组透明度为YES,并且透明度不为1的layer

  • group opacity中alpha并不是分别应用到每一层之上,需要整个layer树画完之后,在统一加上alpha,和底层其他layer的像素进行组合,此时显然无法通过一次遍历就得到结果
  • 需要另外开启一个独立内存,先将layer及其子layer画好,最后给组合后的图层加上alpha进行渲染,将最终结
    果存储到帧缓冲区
  • GroupOpacity 开启离屏渲染的条件是:laver.opacity!=1.0并且有子layer 或者背景图

优化方案:
关闭allowsGroupOpacity属性,根据产品需求自己控制layer透明度

采用了光栅化的layer

如果layer的layer.shouldRasterize被设置为true,会在触发离屏渲染的同时,将光栅化后的内容缓存起来,如果在下一次,对应的layer和子layer没有改变,则复用离屏缓冲区的结果,可以很大程度提升性能
。当视图内容是静态不变时,设置 shouldRasterize(光栅化)为YES,此方案最为实用方便。

imageView.layer.shouldRasterize = YES;
imageView.layer.rasterizationScale = imageView.layer.contentsScale;

但当视图内容是动态变化(如后台下载图片完毕后切换到主线程设置)时,使用此方案反而增加系统负荷。

绘制了文字的layer

想要在 UILabel 和 UITextView 上实现低成本的圆角(不触发离屏渲染),需要保证 layer 的contents呈现透明的背
景色,文本视图类的layer 的contents默认是透明的(字符就在这个透明的环境里绘制、显示),此时只需要设置 la
yer 的backgroundColor, 再加上cornerRacius就可以搞定了。不过 UlLabel 上设置backgroundColor的行为被更
改了,不再是设定layer 的背景色而是为contents设置背景色,UITextView 则没有改变这一点

  • 不要直接利用 labellbackaroundcolor =acolor 设置背景色
  • 不要直接在XIB中为label设置背景色
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 60)];
label.center = CGPointMake(self.view.frame.size.width / 2, 300);
[self.view addSubview:label];
label.text = @"我是label";
label.textAlignment = NSTextAlignmentCenter;
label.layer.borderColor = [UIColor blackColor].CGColor;
label.layer.borderWidth = 2;
label.layer.cornerRadius = 10;
label.layer.masksToBounds = YES;
label.backgroundColor = [UIColor systemCyanColor];

请添加图片描述
优化方案:

//label.layer.masksToBounds = YES;
//label.backgroundColor = [UIColor systemCyanColor];
label.layer.backgroundColor = [UIColor systemCyanColor].CGColor;

请添加图片描述

使用高斯模糊(毛玻璃)效果

iOS屏幕显示推送通知页面或者UIVisualEffectView

EDGE ANTIALIASING(抗锯齿)

不设置 allowsEdgeAntialiasing 属性为YES(默认为NO)

总结

  • RoundedCorner(圆角) 在仅指定cornerRadius时不会触发离屏渲染,仅适用于特殊情况:contents为 nil 或者contents不会遮挡背景色时的圆角。
  • Shawdow 可以通过指定路径来取消离屏渲染。
  • Mask 无法取消离屏渲染,可以利用混合图层来进行优化。
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:26:57  更:2022-10-22 21:30:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:54:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码