本文主要是介绍iOS CAShapeLayer精讲,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
CAShapeLayer继承自CALayer,因此,可使用CALayer的所有属性。但是,CAShapeLayer需要和贝塞尔曲线配合使用才有意义。
关于UIBezierPath,请阅读文章iOS UIBezierPth精讲
基本知识
看看官方说明:
/* The shape layer draws a cubic Bezier spline in its coordinate space.** The spline is described using a CGPath object and may have both fill* and stroke components (in which case the stroke is composited over* the fill). The shape as a whole is composited between the layer's* contents and its first sublayer.*/
上面只是部分说明内容,由于较长,只放一部分出来。这里是说CAShapeLayer是在其坐标系统内绘制贝塞尔曲线的。因此,使用CAShapeLayer需要与UIBezierPath一起使用。
它有一个path属性,而UIBezierPath就是对CGPathRef类型的封装,因此这两者配合起来使用才可以的哦!
@property(nullable) CGPathRef path;
CAShapeLayer和drawRect的比较
drawRect:属于CoreGraphics框架,占用CPU,性能消耗大CAShapeLayer:属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存
这两者各有各的用途,而不是说有了CAShapeLayer就不需要drawRect。
温馨提示:drawRect只是一个方法而已,是UIView的方法,重写此方法可以完成我们的绘制图形功能。
CAShapeLayer与UIBezierPath的关系
CAShapeLayer与UIBezierPath的关系:
CAShapeLayer中shape代表形状的意思,所以需要形状才能生效- 贝塞尔曲线可以创建基于矢量的路径,而
UIBezierPath类是对CGPathRef的封装 - 贝塞尔曲线给
CAShapeLayer提供路径,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了Shape - 用于
CAShapeLayer的贝塞尔曲线作为path,其path是一个首尾相接的闭环的曲线,即使该贝塞尔曲线不是一个闭环的曲线
CAShapeLayer与UIBezierPath画圆
效果图如下:

- (CAShapeLayer *)drawCircle {CAShapeLayer *circleLayer = [CAShapeLayer layer];circleLayer.frame = CGRectMake(0, 0, 200, 200);circleLayer.position = self.view.center;circleLayer.fillColor = [UIColor clearColor].CGColor;circleLayer.lineWidth = 2.0;circleLayer.strokeColor = [UIColor redColor].CGColor;CGRect frame = CGRectMake(0, 0, 200, 200);UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:frame];circleLayer.path = circlePath.CGPath;[self.view.layer addSublayer:circleLayer];return circleLayer;
}
- 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
注意,我们这里不是放在-drawRect:方法中调用的。我们直接将这个CAShaperLayer放到了self.view.layer上,直接呈现出来。
我们创建一个CAShapeLayer,然后配置相关属性,然后再通过UIBezierPath的类方法创建一个内切圆路径,然后将路径指定给CAShapeLayer.path,这就将两者关联起来了。最后,将这个层放到了self.view.layer上呈现出来。
CAShapeLayer与UIBezierPath的简单Loading效果
效果图类似这样(懒自己做图,就百度了一个):

我们调用了上面这个画圆效果的代码:
- (void)drawHalfCircle {self.loadingLayer = [self drawCircle];self.loadingLayer.strokeStart = 0.0;self.loadingLayer.strokeEnd = 0.75;self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1target:selfselector:@selector(updateCircle)userInfo:nilrepeats:YES];
}- (void)updateCircle {if (self.loadingLayer.strokeEnd > 1 && self.loadingLayer.strokeStart < 1) {self.loadingLayer.strokeStart += 0.1;} else if (self.loadingLayer.strokeStart == 0) {self.loadingLayer.strokeEnd += 0.1;}if (self.loadingLayer.strokeEnd == 0) {self.loadingLayer.strokeStart = 0;}if (self.loadingLayer.strokeStart >= 1 && self.loadingLayer.strokeEnd >= 1) {self.loadingLayer.strokeStart = 0;[self.timer invalidate];self.timer = nil;}
}
- 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
我们要实现这个效果,是通过strokeStar和strokeEnd这两个属性来完成的,看看官方说明:
/* These values define the subregion of the path used to draw the* stroked outline. The values must be in the range [0,1] with zero* representing the start of the path and one the end. Values in* between zero and one are interpolated linearly along the path* length. strokeStart defaults to zero and strokeEnd to one. Both are* animatable. */@property CGFloat strokeStart;
@property CGFloat strokeEnd;
这里说明了这两个值的范围是[0,1],当strokeStart的值为0慢慢变成1时,我们看到路径是慢慢消失的。这里实现的效果并不好,因为不能一起循环着。不过,在这里学习的目的已经达到了,后面学习动画效果时,才专门学习它。
源代码下载
小伙伴们可以到github下载:https://github.com/CoderJackyHuang/UIBezierPathLayerDemos
要测试哪种效果,就打开对应的注释就可以了。
这篇关于iOS CAShapeLayer精讲的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!