iOS CAShapeLayer精講
CAShapeLayer繼承自CALayer,因此,可使用CALayer的所有屬性。但是,CAShapeLayer需要和貝塞爾曲線配合使用才有意義。關于
UIBezierPath,請閱讀文章iOS UIBezierPth精講基本知識
看看官方說明:
@PRoperty(nullable) CGPathRef path;CAShapeLayer和drawRect的比較
drawRect:屬于CoreGraphics框架,占用CPU,性能消耗大CAShapeLayer:屬于CoreAnimation框架,通過GPU來渲染圖形,節省性能。動畫渲染直接提交給手機GPU,不消耗內存這兩者各有各的用途,而不是說有了
CAShapeLayer就不需要drawRect。溫馨提示:
drawRect只是一個方法而已,是UIView的方法,重寫此方法可以完成我們的繪制圖形功能。CAShapeLayer與UIBezierPath的關系
CAShapeLayer與UIBezierPath的關系:CAShapeLayer中shape代表形狀的意思,所以需要形狀才能生效貝塞爾曲線可以創建基于矢量的路徑,而UIBezierPath類是對CGPathRef的封裝貝塞爾曲線給CAShapeLayer提供路徑,CAShapeLayer在提供的路徑中進行渲染。路徑會閉環,所以繪制出了Shape用于CAShapeLayer的貝塞爾曲線作為path,其path是一個首尾相接的閉環的曲線,即使該貝塞爾曲線不是一個閉環的曲線CAShapeLayer與UIBezierPath畫圓
效果圖如下:
image- (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
我們調用了上面這個畫圓效果的代碼:
- (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; }}我們要實現這個效果,是通過
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],當
strokeStart的值為0慢慢變成1時,我們看到路徑是慢慢消失的。這里實現的效果并不好,因為不能一起循環著。不過,在這里學習的目的已經達到了,后面學習動畫效果時,才專門學習它。源代碼下載
小伙伴們可以到github下載:https://github.com/CoderJackyHuang/UIBezierPathLayerDemos
要測試哪種效果,就打開對應的注釋就可以了。
新聞熱點
疑難解答