CAShapeLayer与UIBezierPath画出想要的图形

作者: leonardni | 来源:发表于2016-08-21 16:20 被阅读585次

    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: "")
        }
    >    ```
    
    ####效果展示:
    ****
    ![](https://img.haomeiwen.com/i2461501/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矢量图直接转化为:

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

    参考文档:

    iOS CAShapeLayer精讲

    UIBezierPath 精讲

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

    动画可以看:

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

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

    扩展:

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

    CADisplayLink结合UIBezierPath的神奇妙用

    相关文章

      网友评论

        本文标题:CAShapeLayer与UIBezierPath画出想要的图形

        本文链接:https://www.haomeiwen.com/subject/pbcwsttx.html