CAShapeLayer與UIBezierPath畫(huà)出想要的圖形

CAShapeLayer與UIBezierPath畫(huà)出想要的圖形

CAShapeLayer和drawRect的比較

drawRect:屬于CoreGraphics框架,占用CPU,性能消耗大

CAShapeLayer:屬于CoreAnimation框架,通過(guò)GPU來(lái)渲染圖形,節(jié)省性能。動(dòng)畫(huà)渲染直接提交給手機(jī)GPU,不消耗內(nèi)存

這兩者各有各的用途,而不是說(shuō)有了CAShapeLayer就不需要drawRect。

溫馨提示:drawRect只是一個(gè)方法而已,是UIView的方法,重寫(xiě)此方法可以完成我們的繪制圖形功能。

CAShapeLayer與UIBezierPath的關(guān)系:

CAShapeLayer中shape代表形狀的意思,所以需要形狀才能生效
貝塞爾曲線可以創(chuàng)建基于矢量的路徑,而UIBezierPath類是對(duì)CGPathRef的封裝
貝塞爾曲線給CAShapeLayer提供路徑,CAShapeLayer在提供的路徑中進(jìn)行渲染。路徑會(huì)閉環(huán),所以繪制出了Shape
用于CAShapeLayer的貝塞爾曲線作為path,其path是一個(gè)首尾相接的閉環(huán)的曲線,即使該貝塞爾曲線不是一個(gè)閉環(huán)的曲線

使用步驟:

1.繪畫(huà)想要的圖形

使用CAShapeLayer與UIBezierPath可以實(shí)現(xiàn)不在view的drawRect方法中就畫(huà)出一些想要的圖形

步驟:

1、新建UIBezierPath對(duì)象bezierPath
2、新建CAShapeLayer對(duì)象caShapeLayer
3、將bezierPath的CGPath賦值給caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath
4、把caShapeLayer添加到某個(gè)顯示該圖形的layer中

比較麻煩的步驟是對(duì)要繪畫(huà)的圖形點(diǎn)的計(jì)算,比較麻煩。

如下:使用CAShapeLayer實(shí)現(xiàn)復(fù)雜的View的遮罩效果

2.動(dòng)畫(huà)效果

通過(guò)strokeStar和strokeEnd這兩個(gè)屬性來(lái)完成的,看看官方說(shuō)明:

/* 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;

這里說(shuō)明了這兩個(gè)值的范圍是[0,1],當(dāng)strokeEnd的值為0慢慢變成1時(shí),看到路徑是從無(wú)到有正常的繪畫(huà)過(guò)程。當(dāng)strokeStart的值為0慢慢變成1時(shí),我們看到路徑是慢慢消失的。

動(dòng)畫(huà)效果可以用以下兩種方式實(shí)現(xiàn):

  1. 通過(guò)定時(shí)器來(lái)改變strokeStart 或者 strokeEnd 或者 兩個(gè)值 來(lái)實(shí)現(xiàn)動(dòng)畫(huà)效果

引用:github UIBezierPathLayerDemos

- (void)drawHalfCircle {

self.loadingLayer = [self drawCircle];
// 這個(gè)是用于指定畫(huà)筆的開(kāi)始與結(jié)束點(diǎn)
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: "")
    }

第三方庫(kù)

PocketSVG

可以把SVG矢量圖直接轉(zhuǎn)化為:

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

參考文檔:

iOS CAShapeLayer精講

UIBezierPath 精講

使用CAShapeLayer與UIBezierPath畫(huà)出想要的圖形

動(dòng)畫(huà)可以看:

放肆地使用UIBezierPath和CAShapeLayer畫(huà)各種圖形

iOS開(kāi)發(fā)UI篇—核心動(dòng)畫(huà)簡(jiǎn)介

擴(kuò)展:

IOS用CGContextRef畫(huà)各種圖形(文字、圓、直線、弧線、矩形、扇形、橢圓、三角形、圓角矩形、貝塞爾曲線、圖片)

CADisplayLink結(jié)合UIBezierPath的神奇妙用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容