首页 > 其他分享 >iOS Swift圆角绘制与离屏渲染优化

iOS Swift圆角绘制与离屏渲染优化

时间:2023-01-16 17:22:05浏览次数:67  
标签:layer CGPoint Swift iOS 圆角 radii path 离屏

iOS里面使用圆角有可能造成离屏渲染,它需要开辟一个新的内存空间,做上下文切换(状态切换),并且渲染完成后还要进行拷贝操作,因此会造成一定的性能损耗,需要进行优化。

1 原理

https://blog.bombox.org/2020-07-14/ios-offscreen-render/
这篇文章讲了离屏渲染的原理,非常清晰易懂。

离屏渲染的检测方法:

打开最新的Xcode(14.2)运行App
选菜单:Debug -> View Debugging -> Rendering -> Color Offscreen-Rendered Yellow
打开这个选项,看到App里面View的绿色或者黄色就说明发生了离屏渲染。

简单总结产生圆角离屏渲染的条件就是两点:多图层和裁剪

1.1 多图层

当前View有一下几种情况之一就会使用到多图层:

  1. 设置了background
  2. layer添加了子layer
  3. layer设置了mask
  4. 添加了子View

1.2 圆角

总共有4种方法可以产生圆角:

  1. masksToBounds裁剪
  2. layer.mask裁剪
  3. layer绘制圆角
  4. layer绘制圆角补角

4种方法示例如下,灰色是背景色,红色是添加的layer颜色
圆角

masksToBounds裁剪
这种方法是最简单常用的,它只能绘制最简单的圆角,作用于单图层时不会产生离屏渲染

        layer.cornerRadius = 20
        layer.masksToBounds = true

layer.mask裁剪
这种方法能绘制更复杂的圆角遮罩,但是它直接产生离屏渲染

        let maskPath = UIBezierPath(...)        
        let maskLayer = CAShapeLayer()
        maskLayer.path = maskPath.cgPath
        layer.mask = maskLayer

layer绘制圆角
这种方法是生成一个圆角layer,不会产生离屏渲染

        let layer = CAShapeLayer()
        layer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        layer.path = UIBezierPath(roundedRect: layer.frame, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: radii, height: radii)).cgPath
        layer.fillColor = UIColor.red.cgColor

layer绘制圆角补角
这种方法是生成圆角的四个补角的图形layer盖在最上层,不会产生离屏渲染,使用前提是圆角补角的下层或者说背景必须是纯色的

        let w:CGFloat = 200
        let h:CGFloat = 200
        let a90 = Double.pi * 0.5 // 90度

        let path = UIBezierPath()
        
        path.move(to: CGPoint(x: 0, y: radii))
        path.addArc(withCenter: CGPoint(x: radii, y: radii), radius: radii, startAngle: -a90 * 2, endAngle: -a90, clockwise: true)
        path.addLine(to: .zero)
        path.close()
        
        path.move(to: CGPoint(x: w - radii, y: 0))
        path.addArc(withCenter: CGPoint(x: w - radii, y: radii), radius: radii, startAngle: -a90, endAngle: 0, clockwise: true)
        path.addLine(to: CGPoint(x: w, y: 0))
        path.close()
        
        path.move(to: CGPoint(x: w, y: h - radii))
        path.addArc(withCenter: CGPoint(x: w - radii, y: h - radii), radius: radii, startAngle: 0, endAngle: a90, clockwise: true)
        path.addLine(to: CGPoint(x: w, y: h))
        path.close()
        
        path.move(to: CGPoint(x: radii, y: h))
        path.addArc(withCenter: CGPoint(x: radii, y: h - radii), radius: radii, startAngle: a90, endAngle: a90 * 2, clockwise: true)
        path.addLine(to: CGPoint(x: 0, y: h))
        path.close()
        
        let layer = CAShapeLayer()
        layer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        layer.path = path.cgPath
        layer.fillColor = UIColor.red.cgColor

2 圆角场景和使用

对于不同场景,使用不同的圆角方案:

  • 没有子layer或子View的矩形圆角,用masksToBounds;
  • 非矩形圆角或者有子layer子View,用layer绘制圆角;
  • 圆角layer无法盖住时(比如圆角渐变,CAGradientLayer不能直接做圆角),用layer绘制圆角补角覆盖;
  • 如果背景不是纯色,并且用layer绘制圆角补角有问题,就只能用layer.mask裁剪

注意:使用layer的圆角在View的大小变化时需要重新绘制,可以在layoutSubviews或者layoutSublayers方法里做

标签:layer,CGPoint,Swift,iOS,圆角,radii,path,离屏
From: https://www.cnblogs.com/rome753/p/17055930.html

相关文章

  • IOS中Object-C按照NSDictionary中的某个Key排序的方法
    //create_time降序NSComparisonResultsort_desc(NSDictionary*firstDict,NSDictionary*secondDict,void*context){NSDateFormatter*dateFormatter=[[NSD......
  • axios_socketio_cros_test
    D:\code_gitee\html_crostest\htmo_crostest\index.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><linkrel="icon"type="image/sv......
  • 新建的nagios,本地RHEL6.0报HTTP/1.1--403错误
    新建的nagios,本地RHEL6.0报HTTP/1.1--403错误 HTTPWARNING:HTTP/1.1403Forbidden-4184bytesin0.001secondresponsetime是因为nagios不断地检查apahce的根目录,......
  • iostat
    iostat命令用途报告中央处理器(CPU)统计信息和整个系统、适配器、tty设备、磁盘和CD-ROM的输入/输出统计信息。 语法 iostat[-s][-a][-d|-t][-T][-m][PhysicalVolume.......
  • axios 进行同步请求(async+await+promise)
    axios进行同步请求(async+await+promise)遇到的问题介绍将axios的异步请求改为同步请求想到了async 和await、Promiseaxios介绍Axios 是一个基于 promise 的HT......
  • ios网络协议从http变成https
    最近发了一个很蛋疼的事,iphone16.x以后的系统浏览器自动将http请求切换为https请求了工程自测1.在ihone14promax,iOS16.1的手机上用http请求是失败的,在iPhonese2,iOS16.......
  • ios苹果app上架流程
    iOSAPP发布分两大步骤,首先测试APP,如没问题再上传APP审核!1、真机测试调试APP2、上传APP到AppStore审核上架基本需求资料1、苹果开发者账号(如还没账号先申请)2、开发好的APP......
  • [ios开发]-APP-上架流程
    ​由于苹果的机制,在非越狱机器上安装必须通过官方的Appstore,开发者开发好应用后上传Appstore,也需要通过审核等环节。AppCan作为一个跨主流平台的一个开发平台,也对ipa包上......
  • day08-Axios
    Axios1.基本说明Axios是一个基于promise的网络请求库,作用于node.js和浏览器中。它是isomorphic的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生n......
  • axios 处理响应( 流文件或 json)
    今天遇到一前端问题。axios导出后台xls文件出现乱码。多会儿没写发现前端了,发现是【没指定响应类型时,axios默认把响应内容包成字符串,即type(res.data)='string'】,......