CAShapeLayer
一、CAShapeLayer的作用和优点
可以通过矢量图形而不是bitmap来绘制的图层子类。你指定诸如颜色和线宽等属性,用CGPath
来定义想要绘制的图形
你也可以用Core Graphics直接向原始的CALyer
的内容中绘制一个路径,相比直下,使用CAShapeLayer
有以下一些优点:
- 渲染快速。
CAShapeLayer
使用了硬件加速,绘制同一图形会比用Core Graphics快很多。 - 高效使用内存。一个
CAShapeLayer
不需要像普通CALayer
一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。 - 不会被图层边界剪裁掉。一个
CAShapeLayer
可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer
一样被剪裁掉(如我们在第二章所见)。 - 不会出现像素化。当你给
CAShapeLayer
做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。
二、实际例子
三、上面的例子是二维码扫描界面,界面中需要一个中间透明的提示框,以及四个直角的标记,可以通过CASharpLayer来实现
中间的透明可以通过UIview的maskLayer来进行掩码实现
四个角的黄线通过CASharpLayer来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | - ( void )addOverlay {<br> //innerrect就是中空的frame CGRect innerRect = [ self getInnerRect]; UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self .bounds.size.width, self .bounds.size.height) cornerRadius:0]; UIBezierPath *circlePath = [UIBezierPath bezierPathWithRoundedRect:innerRect cornerRadius:0]; [path appendPath:circlePath]; [path setUsesEvenOddFillRule: YES ]; CAShapeLayer *fillLayer = [CAShapeLayer layer]; fillLayer.path = path.CGPath; fillLayer.fillRule = kCAFillRuleEvenOdd; fillLayer.fillColor = [UIColor blackColor].CGColor; fillLayer.opacity = 0.5; [ self .layer addSublayer:fillLayer]; _maskLayer = fillLayer; _overlay = [[CAShapeLayer alloc] init]; _overlay.backgroundColor = [UIColor clearColor].CGColor; _overlay.fillColor = [UIColor clearColor].CGColor; _overlay.strokeColor = [UIColor yellowColor].CGColor; _overlay.lineWidth = 3; innerRect = CGRectInset(innerRect, -_overlay.lineWidth/2, -_overlay.lineWidth/2); CGFloat lineLength = 20; UIBezierPath *cornerPath = [UIBezierPath bezierPath]; //left-top corner CGPoint leftTop = CGPointMake(innerRect.origin.x, innerRect.origin.y); [cornerPath moveToPoint:CGPointMake(leftTop.x, leftTop.y + lineLength)]; [cornerPath addLineToPoint:leftTop]; [cornerPath addLineToPoint:CGPointMake(leftTop.x + lineLength, leftTop.y)]; //right-top corner CGPoint rightTop = CGPointMake(innerRect.origin.x + innerRect.size.width, innerRect.origin.y); [cornerPath moveToPoint:CGPointMake(rightTop.x - lineLength, rightTop.y)]; [cornerPath addLineToPoint:rightTop]; [cornerPath addLineToPoint:CGPointMake(rightTop.x, rightTop.y + lineLength)]; //right-bottom corner CGPoint rightBottom = CGPointMake(innerRect.origin.x + innerRect.size.width, innerRect.origin.y + innerRect.size.height); [cornerPath moveToPoint:CGPointMake(rightBottom.x, rightBottom.y - lineLength)]; [cornerPath addLineToPoint:rightBottom]; [cornerPath addLineToPoint:CGPointMake(rightBottom.x - lineLength, rightBottom.y)]; //left-bottom corner CGPoint leftBottom = CGPointMake(innerRect.origin.x, innerRect.origin.y + innerRect.size.height); [cornerPath moveToPoint:CGPointMake(leftBottom.x + lineLength, leftBottom.y)]; [cornerPath addLineToPoint:leftBottom]; [cornerPath addLineToPoint:CGPointMake(leftBottom.x, leftBottom.y - lineLength)]; _overlay.path = cornerPath.CGPath; [ self .layer addSublayer:_overlay]; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架