GPU屏幕渲染有两种方式:
1、On-Screen Rendering(当前屏幕渲染)
指的是GPU的渲染操作是在当前显示的屏幕缓冲区进行。
2、Off-Screen Rendering(离屏渲染)
指的是GPU在当前屏幕缓冲区以外开辟一个缓冲区进行渲染操作。
离屏渲染的代价很高体现在两个方面,1、需要创建一个新的缓冲区。2、上下文切换操作。

会引发离屏渲染的操作:
1、为图层设置遮罩(layer.mask)
2、为图层设置阴影(layer.shadow)
3、为图层设置光栅化(layer.shouldRasterize = true)
4、设置layer.masksToBounds/view.clipsToBounds属性为true
5、使用CGContext在drawRect方法中绘制会耗费更多的内存。

优化方案:
iOS 9.0之前 UIImageView和UIButton设置圆角都会触发离屏渲染。
iOS 9.0之后 UIButton设置圆角会触发离屏渲染,而UIImageView里png图片并不会触发离屏渲染了,如果设置其他阴影效果之类的还是会触发离屏渲染的。

1、UIView(不包括子类)、UILabel、UITextField、UITextView,直接使用layer.cornerRadius 一行代码就行。

2、UIImageView 推荐使用方法二
方法一:使用贝塞尔曲线和CAShapeLayer,生成一个圆角layer,作为视图的layer.mask ,该方法会触发离屏渲染
- (CAShapeLayer *)creatShapLayerBounds:(CGRect)bounds {
UIBezierPath *bezier = [UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:bounds.size.height / 2];
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.frame = bounds;
layer.path = bezier.CGPath;
return layer;
}

方法二:使用贝塞尔曲线绘制路径,并切除多余视图,然后用view重新绘制(drawRect),该方法不会触发离屏渲染,据说会重写drawRect方法会耗费大量内存,本人用xcode测试并未发现。
- (void)drawImageView:(UIImageView *)imageview

{
UIGraphicsBeginImageContextWithOptions(imageview.bounds.size, NO, [UIScreen mainScreen].scale);
[[UIBezierPath bezierPathWithRoundedRect:imageview.bounds cornerRadius:imageview.bounds.size.height] addClip];
[imageview drawRect:view.bounds];
imageview.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}

方法三:使用贝塞尔曲线绘制路径,用CGContext重绘UIImage(drawInRect),该方法也不会触发离屏渲染,但是内存会暴增。

  • (UIImage *)drawRectWithImage:(UIImage *)image
    {
    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
    UIBezierPath *bezier = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:rect.size.height];
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
    CGContextAddPath(UIGraphicsGetCurrentContext(), bezier.CGPath);
    CGContextClip(UIGraphicsGetCurrentContext());
    [image drawInRect:rect];
    CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
    }

3、UIButton
1、如果是简单的设置背景色、添加边框,可以使用上面的方法一,用贝塞尔曲线和CAShaplayer,然后将CAShaplayer添加到button的layer层上。
2、如果是设置Image,可以使用上面的方法三,drawInRect重新绘制UIImage。
3、也可以用一个中间透明,四周跟背景色相同的图片贴在button。
4、或者图片直接让UI切好,减少客户端代码量。

3、阴影(shadow)优化
通过设置shadowPath来代替shadowOffset能大幅提高性能。
imageview.layer.shadowColor = [UIColor grayColor].CGColor;
imageview.layer.shadowOpacity = 0;
imageview.layer.shadowRadius = 2.0;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:imageview.frame];
imageview.layer.shadowPath = path.CGPath;

iOS 切圆角离屏渲染问题相关推荐

  1. ios开发之离屏渲染

    前言 在介绍离屏渲染之前,首先理解下这个概念,什么是离屏渲染,为什么会出现离屏渲染,以及如何避免离屏渲染. GPU屏幕渲染有两种方式: (1)On-Screen Rendering (当前屏幕渲染) ...

  2. iOS 切圆角 任意几个角

    使用前提是不能使用mansory 得使用frame布局! 1.如果是切四个角的圆角,代码示例: self.picImage.layer.cornerRadius = 8; self.picImage. ...

  3. iOS圆角避免离屏渲染

    写在前面 代码已经整理到nxlib的 nx_circleView, nx_circleImage 中, 在列表中使用圆角时建议使用这个方式. 参考阅读 离屏渲染优化详解:实例示范+性能测试 使用 In ...

  4. iOS 和常见的离屏渲染Say Goodbye!

    移动应用优化到最后主要还是看FPS(页面流畅程度)性能.内存占用等方面.离屏渲染也是老生常谈的一个问题,本文侧重点在常见导致离屏渲染的因素及解决方案. 那么为什么离屏渲染会引起性能问题? OpenGL ...

  5. 关于iOS离屏渲染的深入研究

    在平时的iOS面试中,我们经常会考察有关离屏渲染(Offscreen rendering)的知识点.一般来说,绝大多数人都能答出"圆角.mask.阴影会触发离屏渲染",但是也仅止于 ...

  6. iOS之从OpenGL深入探究离屏渲染及性能优化

    一.探究内容 到底什么是离屏渲染?是在GPU上面还是CPU上面执行的? 为什么要有离屏渲染?什么情况下会产生离屏渲染? 帧缓冲区是什么?当前屏幕缓冲区和屏幕外缓冲区又是什么? 切换缓冲区是什么操作?真 ...

  7. iOS 离屏渲染的研究

    GPU渲染机制: CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示. G ...

  8. ios swift 5 UIView切圆角,指定某几个角,2个,左上,左下,右上,右下

    文章目录 代码 注意 参考博客: 代码 extension UIView {//radius:切圆角的半径//corner:要切四个角中的哪个角func cornerCut(radius:Int,co ...

  9. 【iOS高级资深工程师面试篇】①、2022年,金九银十我为你准备了《iOS高级资深工程师面试知识总结》 UI部分3/3 -UIView绘制原理-离屏渲染

    iOS高级资深工程师面试篇系列 - 已更新3篇 UI部分1/3 -UITableView-事件传递&视图响应 UI部分2/3 -图像显示原理-UI卡顿&掉帧 UI部分3/3 -UIVi ...

最新文章

  1. html用vue传递数据,Vue组件及数据传递详解
  2. 人力资源部如何运用OKR?看三大层面最新OKR模板
  3. 一个小菜程序员的经历
  4. 英伟达Q2营收大涨50%,创下历史新高,游戏业务已不是最大收入来源
  5. python怎么读取列表-Python如何获取列表(List)的中位数
  6. c语言解决函数变参数问题 va_list
  7. Webstorm修改svn时提示Error relocating working copy:Server SSL certificate rejected
  8. css获取到指定元素的宽度,在回调返回宽度值
  9. H.264中POC类型之探讨
  10. JS高级——await-async
  11. AI在出行场景的应用实践:路线规划、ETA、动态事件挖掘…
  12. 转行IT行业的心路历程3
  13. 11.MongoDB之副本集与Oplog
  14. 计算机如何安装pdf,pdf虚拟打印机是什么?怎么安装到电脑里
  15. 60款mac超酷炫动态苹果免费屏保壁纸
  16. 对讲机在哪插卡?插卡对讲机是什么意思呢?5000公里对讲机的哪点事
  17. 证件照换底色,快速简单!(附去水印宝藏工具)
  18. 爱签:如何在线签订电子合同
  19. 基于机智云物联网平台4孔插座开源
  20. 【WORD技巧合集】

热门文章

  1. 县市经济负债升级问题严重,数字化智能化转型升级势在必行,县域知识经济创新枢纽项目,宏微两端的突破点相互照应的连贯呼应需要融智学的启迪引领
  2. 每当我听到我会唱的歌我就会觉得世界不公得好可爱
  3. Arduino系列教程之 – PWM 的秘密(下)
  4. 呆滞库存的处理方式与预防办法
  5. 力扣 174. 地下城游戏 DFS + Python
  6. 《Java》使用面向对象的方法制作的小游戏
  7. HA(High Availability高可用性)
  8. 通达信众赢全部指标(源码副图)
  9. 教你解决鼠标右键失灵的问题
  10. ASP.NET教程(一) 概述