iOS CAShapeLayer精講
CAShapeLayer繼承自CALayer,因此,可使用CALayer的所有屬性。但是,CAShapeLayer需要和貝塞爾曲線配合使用才有意義。關(guān)于
UIBezierPath,請(qǐng)閱讀文章iOS UIBezierPth精講基本知識(shí)
看看官方說(shuō)明:
@PRoperty(nullable) CGPathRef path;CAShapeLayer和drawRect的比較
drawRect:屬于CoreGraphics框架,占用CPU,性能消耗大CAShapeLayer:屬于CoreAnimation框架,通過(guò)GPU來(lái)渲染圖形,節(jié)省性能。動(dòng)畫渲染直接提交給手機(jī)GPU,不消耗內(nèi)存這兩者各有各的用途,而不是說(shuō)有了
CAShapeLayer就不需要drawRect。溫馨提示:
drawRect只是一個(gè)方法而已,是UIView的方法,重寫此方法可以完成我們的繪制圖形功能。CAShapeLayer與UIBezierPath的關(guān)系
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)的曲線CAShapeLayer與UIBezierPath畫圓
效果圖如下:
image- (CAShapeLayer *)drawCircle { CAShapeLayer *circleLayer = [CAShapeLayer layer]; // 指定frame,只是為了設(shè)置寬度和高度 circleLayer.frame = CGRectMake(0, 0, 200, 200); // 設(shè)置居中顯示 circleLayer.position = self.view.center; // 設(shè)置填充顏色 circleLayer.fillColor = [UIColor clearColor].CGColor; // 設(shè)置線寬 circleLayer.lineWidth = 2.0; // 設(shè)置線的顏色 circleLayer.strokeColor = [UIColor redColor].CGColor; // 使用UIBezierPath創(chuàng)建路徑 CGRect frame = CGRectMake(0, 0, 200, 200); UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:frame]; // 設(shè)置CAShapeLayer與UIBezierPath關(guān)聯(lián) circleLayer.path = circlePath.CGPath; // 將CAShaperLayer放到某個(gè)層上顯示 [self.view.layer addSublayer:circleLayer]; return circleLayer;}
注意,我們這里不是放在
-drawRect:方法中調(diào)用的。我們直接將這個(gè)CAShaperLayer放到了self.view.layer上,直接呈現(xiàn)出來(lái)。我們創(chuàng)建一個(gè)
CAShapeLayer,然后配置相關(guān)屬性,然后再通過(guò)UIBezierPath的類方法創(chuàng)建一個(gè)內(nèi)切圓路徑,然后將路徑指定給CAShapeLayer.path,這就將兩者關(guān)聯(lián)起來(lái)了。最后,將這個(gè)層放到了self.view.layer上呈現(xiàn)出來(lái)。CAShapeLayer與UIBezierPath的簡(jiǎn)單Loading效果
效果圖類似這樣(懶自己做圖,就百度了一個(gè)):
image
我們調(diào)用了上面這個(gè)畫圓效果的代碼:
- (void)drawHalfCircle { self.loadingLayer = [self drawCircle]; // 這個(gè)是用于指定畫筆的開(kāi)始與結(jié)束點(diǎn) 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; }}我們要實(shí)現(xiàn)這個(gè)效果,是通過(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)
strokeStart的值為0慢慢變成1時(shí),我們看到路徑是慢慢消失的。這里實(shí)現(xiàn)的效果并不好,因?yàn)椴荒芤黄鹧h(huán)著。不過(guò),在這里學(xué)習(xí)的目的已經(jīng)達(dá)到了,后面學(xué)習(xí)動(dòng)畫效果時(shí),才專門學(xué)習(xí)它。源代碼下載
小伙伴們可以到github下載:https://github.com/CoderJackyHuang/UIBezierPathLayerDemos
要測(cè)試哪種效果,就打開(kāi)對(duì)應(yīng)的注釋就可以了。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注