iOS CAShapeLayer精講

CAShapeLayer繼承自CALayer,所以,可以使用CALayer的全部屬性。可是,CAShapeLayer須要和貝塞爾曲線配合使用纔有意義。git

關於UIBezierPath,請閱讀文章iOS UIBezierPth精講github

基本知識


看看官方說明:框架

1性能

2學習

3測試

4動畫

5ui

6spa

7code

8

9

 

/* The shape layer draws a cubic Bezier spline in its coordinate space.

*

* The spline is described using a CGPath object and may have both fill

* and stroke components (in which case the stroke is composited over

* the fill). The shape as a whole is composited between the layer's

* contents and its first sublayer.

*/

 

上面只是部分說明內容,因爲較長,只放一部分出來。這裏是說CAShapeLayer是在其座標系統內繪製貝塞爾曲線的。所以,使用CAShapeLayer須要與UIBezierPath一塊兒使用。

它有一個path屬性,而UIBezierPath就是對CGPathRef類型的封裝,所以這二者配合起來使用才能夠的哦!

1

2

3

 

@property(nullable) CGPathRef path;

 

CAShapeLayer和drawRect的比較


  • drawRect:屬於CoreGraphics框架,佔用CPU,性能消耗大

  • CAShapeLayer:屬於CoreAnimation框架,經過GPU來渲染圖形,節省性能。動畫渲染直接提交給手機GPU,不消耗內存

這二者各有各的用途,而不是說有了CAShapeLayer就不須要drawRect

舒適提示:drawRect只是一個方法而已,是UIView的方法,重寫此方法能夠完成咱們的繪製圖形功能。

CAShapeLayer與UIBezierPath的關係


CAShapeLayerUIBezierPath的關係:

  1. CAShapeLayershape表明形狀的意思,因此須要形狀才能生效

  2. 貝塞爾曲線能夠建立基於矢量的路徑,而UIBezierPath類是對CGPathRef的封裝

  3. 貝塞爾曲線給CAShapeLayer提供路徑,CAShapeLayer在提供的路徑中進行渲染。路徑會閉環,因此繪製出了Shape

  4. 用於CAShapeLayer的貝塞爾曲線做爲path,其path是一個首尾相接的閉環的曲線,即便該貝塞爾曲線不是一個閉環的曲線

CAShapeLayer與UIBezierPath畫圓


效果圖以下:

image

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

 

- (CAShapeLayer *)drawCircle {

  CAShapeLayer *circleLayer = [CAShapeLayer layer];

  // 指定frame,只是爲了設置寬度和高度

  circleLayer.frame = CGRectMake(0, 0, 200, 200);

  // 設置居中顯示

  circleLayer.position = self.view.center;

  // 設置填充顏色

  circleLayer.fillColor = [UIColor clearColor].CGColor;

  // 設置線寬

  circleLayer.lineWidth = 2.0;

  // 設置線的顏色

  circleLayer.strokeColor = [UIColor redColor].CGColor;

  

  // 使用UIBezierPath建立路徑

  CGRect frame = CGRectMake(0, 0, 200, 200);

  UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:frame];

  

  // 設置CAShapeLayer與UIBezierPath關聯

  circleLayer.path = circlePath.CGPath;

  

  // 將CAShaperLayer放到某個層上顯示

  [self.view.layer addSublayer:circleLayer];

  

  return circleLayer;

}

 

注意,咱們這裏不是放在-drawRect:方法中調用的。咱們直接將這個CAShaperLayer放到了self.view.layer上,直接呈現出來。

咱們建立一個CAShapeLayer,而後配置相關屬性,而後再經過UIBezierPath的類方法建立一個內切圓路徑,而後將路徑指定給CAShapeLayer.path,這就將二者關聯起來了。最後,將這個層放到了self.view.layer上呈現出來。

CAShapeLayer與UIBezierPath的簡單Loading效果


效果圖相似這樣(懶本身作圖,就百度了一個):

image

咱們調用了上面這個畫圓效果的代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

 

- (void)drawHalfCircle {

  self.loadingLayer = [self drawCircle];

  

  // 這個是用於指定畫筆的開始與結束點

  self.loadingLayer.strokeStart = 0.0;

  self.loadingLayer.strokeEnd = 0.75;

  

  self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1

                                                target:self

                                              selector:@selector(updateCircle)

                                              userInfo:nil

                                               repeats: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;

  }

}

 

咱們要實現這個效果,是經過strokeStarstrokeEnd這兩個屬性來完成的,看看官方說明:

1

2

3

4

5

6

7

8

9

10

11

 

/* 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],當strokeStart的值爲0慢慢變成1時,咱們看到路徑是慢慢消失的。這裏實現的效果並很差,由於不能一塊兒循環着。不過,在這裏學習的目的已經達到了,後面學習動畫效果時,才專門學習它。

源代碼下載


小夥伴們能夠到github下載:https://github.com/CoderJackyHuang/UIBezierPathLayerDemos

要測試哪一種效果,就打開對應的註釋就能夠了。

相關文章
相關標籤/搜索