CAShapeLayer与UIBezierPath画出想要的图形
CAShapeLayer和drawRect的比较
drawRect:属于CoreGraphics框架,占用CPU,性能消耗大
CAShapeLayer:属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存
这两者各有各的用途,而不是说有了CAShapeLayer就不需要drawRect。
温馨提示:drawRect只是一个方法而已,是UIView的方法,重写此方法可以完成我们的绘制图形功能。
CAShapeLayer与UIBezierPath的关系:
CAShapeLayer中shape代表形状的意思,所以需要形状才能生效
贝塞尔曲线可以创建基于矢量的路径,而UIBezierPath类是对CGPathRef的封装
贝塞尔曲线给CAShapeLayer提供路径,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了Shape
用于CAShapeLayer的贝塞尔曲线作为path,其path是一个首尾相接的闭环的曲线,即使该贝塞尔曲线不是一个闭环的曲线
使用步骤:
1.绘画想要的图形
使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形
步骤:
1、新建UIBezierPath对象bezierPath
2、新建CAShapeLayer对象caShapeLayer
3、将bezierPath的CGPath赋值给caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath
4、把caShapeLayer添加到某个显示该图形的layer中
比较麻烦的步骤是对要绘画的图形点的计算,比较麻烦。
如下:使用CAShapeLayer实现复杂的View的遮罩效果
2.动画效果
通过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],当strokeEnd的值为0慢慢变成1时,看到路径是从无到有正常的绘画过程。当strokeStart的值为0慢慢变成1时,我们看到路径是慢慢消失的。
动画效果可以用以下两种方式实现:
- 通过定时器来改变strokeStart 或者 strokeEnd 或者 两个值 来实现动画效果
引用:github UIBezierPathLayerDemos
- (void)drawHalfCircle {
self.loadingLayer = [self drawCircle];
// 这个是用于指定画笔的开始与结束点
self.loadingLayer.strokeStart = 0.0;
self.loadingLayer.strokeEnd = 0.75;
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.2f
target:self
selector:@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;
}
}
>
>2. 使用 CABasicAnimation
> 如:
>
> ```swift
> private func animation1() {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 2
layer.addAnimation(animation, forKey: "")
}
> ```
####效果展示:
****
![](http://upload-images.jianshu.io/upload_images/2461501-8dd5e4840f16a115.gif?imageMogr2/auto-orient/strip)
```swift
private func animation1() {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 2
layer.addAnimation(animation, forKey: "")
}
private func animation2() {
layer.strokeStart = 0.5
layer.strokeEnd = 0.5
let animation = CABasicAnimation(keyPath: "strokeStart")
animation.fromValue = 0.5
animation.toValue = 0
animation.duration = 2
let animation2 = CABasicAnimation(keyPath: "strokeEnd")
animation2.fromValue = 0.5
animation2.toValue = 1
animation2.duration = 2
layer.addAnimation(animation, forKey: "")
layer.addAnimation(animation2, forKey: "")
}
第三方库
PocketSVG
可以把SVG矢量图直接转化为:
- CGPaths
- CAShapeLayers
- UIBezierPaths
- NSBezierCurves
参考文档:
iOS CAShapeLayer精讲
UIBezierPath 精讲
使用CAShapeLayer与UIBezierPath画出想要的图形
动画可以看:
放肆地使用UIBezierPath和CAShapeLayer画各种图形
iOS开发UI篇—核心动画简介
扩展:
IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
CADisplayLink结合UIBezierPath的神奇妙用