貝塞爾曲線與CAShapeLayer簡單使用
首先,要知道CAShapeLayer繼承自CALayer 可以使用CALayer的所有屬性,其次CAShapeLayer需要與貝塞爾曲線使用才有意義,CAShapeLayer可以畫出一些想要的圖形
注意:一般我們知道view的drawRect可以繪制想要的圖形,但是drawRect屬于CoreGraphics框架,走的是CPU消耗性能較大。CAShapeLayer屬于CoreAnimation框架,將動畫渲染提交到GPU,消耗相對較小。
首先解釋一下貝塞爾曲線(有興趣的在看,沒看不影響后面的內容理解,可跳過)
這些是我個人理解的如果有不對請指出。
貝塞爾曲線可以有1到多階的 1階、2階、3階。。。。
最簡單的一階,就是有一個點比如P0,沿著P0到P1這條線段移動的路徑就是他的曲線。
一階貝塞爾曲線.png
二階是由2個點,比如A1、B1沿著線段P0P1、P1P2開始移動時,兩個點所構成的線段A1B1,二階貝塞爾曲線就是在A1B1這條線變化的線段上移動的路徑。就是下圖紅色的。
二階貝塞爾曲線.png
實在太難畫了....還是找張圖吧。。
二階貝塞爾曲線.gif
三階就是3個點在三條線段上移動時,這三個點構成的2條變化的線段,在這兩條變化的線段上,又有2個點在移動,最后這兩個點又構成了一條線段,這條線段上有一個點在移動,這個點移動的路徑就是貝塞爾曲線。圖自行百度吧。至于后面幾階可以類推得到。
代碼部分
// 創建一個矩形貝塞爾曲線
// UIBezierPath *rect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 250, 150)];
// 創建一個橢圓貝塞爾曲線,要創建一個圓的話,寬高設置成一樣的就行了。
// UIBezierPath *oval = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 250, 150)];
UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 100, 100)];
// 創建CAShapeLayer
CAShapeLayer *shape = [CAShapeLayer layer];
shape.frame = CGRectMake(0, 0, 150, 150);
shape.position = self.view.center;
// 圖形的填充色
shape.fillColor = [UIColor grayColor].CGColor;
// 這個是背景顏色并不是圖形的顏色,而是shape.frame除去圖形其他背景部分的顏色。
// shape.backgroundColor = [UIColor redColor].CGColor;
// CAShapeLayer與貝塞爾曲線的關聯
shape.path = circle.CGPath;
[self.view.layer addSublayer:shape];
/* 從上面的代碼可以看出CAShapeLayer和貝塞爾曲線的frame值并不相同,但是不影響圖形的繪畫,所以它們的frame互不干擾。
只不過要處理好,我們不能創建的CAShapeLayer的frame小于貝塞爾曲線 因為如果這樣只要設置了masksToBounds這個屬性會把超出部分截掉。*/
// shape.masksToBounds = YES;
還有StrokeStart和StrokeEnd隱式動畫
先將上面代碼的CAShapeLayer設成全局的 然后填充顏色設置為clear
再設置下面這些屬性,并添加定時器。
self.shape.fillColor = [UIColor clearColor].CGColor;
//線段寬度
self.shape.lineWidth = 1.f;
//線段顏色
self.shape.strokeColor = [UIColor greenColor].CGColor;
//開始位置和結束位置 整個圓是1 注:3點鐘方向為0,順時針
self.shape.strokeStart = 0.25;
self.shape.strokeEnd = 0.5;
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action) userInfo:nil repeats:YES];
- (void)action{
CGFloat a = arc4random() % 100 / 100.f;
CGFloat b = arc4random() % 100 / 100.f;
// 開始值一定要小于結束值
self.shape.strokeStart = a < b ? a : b;
self.shape.strokeEnd = a > b ? a : b;
}
最后有一點,用于CAShapeLayer的貝塞爾曲線作為path,其path是一個首尾相接的閉環曲線即使該貝塞爾曲線不是閉環曲線。
可以嘗試用這個寫進度條也很方便。
來自:http://www.jianshu.com/p/792a728b0a44