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];
}

  

 

posted @   兜兜有糖的博客  阅读(650)  评论(0编辑  收藏  举报
编辑推荐:
· 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 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示