CAShapeLayer与UIBezierPath画出想要的图形

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时,我们看到路径是慢慢消失的。

动画效果可以用以下两种方式实现:

  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: "")
    }
CAShapeLayer与UIBezierPath画出想要的图形_第1张图片
      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矢量图直接转化为:

  1. CGPaths
  2. CAShapeLayers
  3. UIBezierPaths
  4. NSBezierCurves

参考文档:

iOS CAShapeLayer精讲

UIBezierPath 精讲

使用CAShapeLayer与UIBezierPath画出想要的图形

动画可以看:

放肆地使用UIBezierPath和CAShapeLayer画各种图形

iOS开发UI篇—核心动画简介

扩展:

IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

CADisplayLink结合UIBezierPath的神奇妙用

你可能感兴趣的:(CAShapeLayer与UIBezierPath画出想要的图形)