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):
- 通過(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: "")
}
> ```
####效果展示:
****

```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ù)
可以把SVG矢量圖直接轉(zhuǎn)化為:
- CGPaths
- CAShapeLayers
- UIBezierPaths
- NSBezierCurves
參考文檔:
使用CAShapeLayer與UIBezierPath畫(huà)出想要的圖形
動(dòng)畫(huà)可以看:
放肆地使用UIBezierPath和CAShapeLayer畫(huà)各種圖形
iOS開(kāi)發(fā)UI篇—核心動(dòng)畫(huà)簡(jiǎn)介
擴(kuò)展:
IOS用CGContextRef畫(huà)各種圖形(文字、圓、直線、弧線、矩形、扇形、橢圓、三角形、圓角矩形、貝塞爾曲線、圖片)