UIKit中咱們使用的UIView、UILabel等控件其實顯示的載體都是CALayer及其子類,好比CATextLayer、CAScrollLayer等。咱們在作Layer層動畫的時候則使用的CAShapeLayer比較多。經過CoreAnimal中的CABasicAnimation結合path來實現。git
以前都是經過長篇幅的介紹一些理論知識,此次經過一個個的小案例,由簡到繁一步步介紹。github
// UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 100, 100)];
// UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 120)];//當寬高同樣的時候就是圓,不然就是橢圓
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 100, 120) cornerRadius:90];//首先是畫一個矩形,而後再設置四個角的角度
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:80 startAngle:-M_PI_2 endAngle:M_PI/2 clockwise:YES];//以point爲中心,radius的值爲半徑畫弧。此弧的開始角度爲startAngle,結束角度爲endAngle,這兩個數值是弧度,不是角度。clockwise是畫此弧是按照順時針仍是逆時針
CAShapeLayer *pointLayer = [CAShapeLayer layer];
pointLayer.path = path.CGPath;
pointLayer.strokeColor = [[UIColor redColor] CGColor];//線條顏色
pointLayer.lineWidth = 10;
// kCALineCapButt 直角
// kCALineCapRound 圓角
// kCALineCapSquare 與kCGLineCapButt是同樣的,可是比kCGLineCapButt長一點
pointLayer.lineCap = kCALineCapRound;//當線條是單獨的沒有與其餘線鏈接的時候,此時線頭的形狀
[self.view.layer addSublayer:pointLayer];
複製代碼
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 200) radius:80 startAngle:-M_PI_2 endAngle:M_PI*3/2 clockwise:YES];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.lineWidth = 10;
layer.path = path.CGPath;
layer.strokeColor = [UIColor purpleColor].CGColor;
layer.fillColor = [UIColor orangeColor].CGColor;
layer.strokeStart = 0.5;
layer.strokeEnd = 0.8;
[self.view.layer addSublayer:layer];
複製代碼
CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = CGRectMake(100, 300, 20, 100);
UIColor *middleColor = [UIColor colorWithWhite:255/255 alpha:0.8];
NSArray *colors = @[
(__bridge id)[UIColor redColor].CGColor,
(__bridge id)middleColor.CGColor,
(__bridge id)[UIColor redColor].CGColor
];
layer.colors = colors;
[self.view.layer addSublayer:layer];
layer.startPoint = CGPointMake(0, 0);
layer.endPoint = CGPointMake(1, 0);
[self.view.layer addSublayer:layer];
複製代碼
假設咱們想經過路徑漸變應該怎麼辦呢?好比一個半圓弧的漸變(能夠思考一下怎麼實現,下邊會有實現的)bash
如下代碼是首先畫了一個正方形,填充顏色是紅色,而後畫了一個圓形。圓形是正方形的遮罩層 若是你們瞭解ps的話,其實遮罩層就是ps中的蒙版的概念。 遮罩層不會顯示出來,遮罩層有顏色的區域纔會將被遮罩層顯示出來,沒有顏色的不會顯示出來app
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) cornerRadius:50];//圓形
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = CGRectMake(0, 0, 100, 100);
maskLayer.path = maskPath.CGPath;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];//正方形
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.path = path.CGPath;
layer.fillColor = [UIColor redColor].CGColor;
layer.mask = maskLayer;//設置遮罩層
[self.view.layer addSublayer:layer];
複製代碼
上邊的問題不知道你們有沒有思路了呢?測試
UIBezierPath *path1 = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];//正方形
UIBezierPath *path2 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) cornerRadius:50];//圓形
[path1 appendPath:path2];//結合兩個路徑
CAShapeLayer *shapLayer = [CAShapeLayer layer];
shapLayer.frame = CGRectMake(50, 50, 100, 100);
shapLayer.fillColor = [UIColor blackColor].CGColor;
shapLayer.fillRule = kCAFillRuleEvenOdd;
shapLayer.path = path1.CGPath;
shapLayer.lineWidth = 0.5;
[self.view.layer addSublayer:shapLayer];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.fillColor = [UIColor redColor].CGColor;
layer.path= path1.CGPath;
[self.view.layer insertSublayer:layer below:shapLayer];//設置一個背景,這樣看的效果更好一些
複製代碼
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:80 startAngle:-M_PI_2 endAngle:M_PI/2 clockwise:YES];//以point爲中心,radius的值爲半徑畫弧。此弧的開始角度爲startAngle,結束角度爲endAngle,這兩個數值是弧度,不是角度。clockwise是畫此弧是按照順時針仍是逆時針
CAShapeLayer *pointLayer = [CAShapeLayer layer];
pointLayer.path = path.CGPath;
pointLayer.strokeColor = [[UIColor blackColor] CGColor];//線條顏色
// kCAFillModeRemoved 這個是默認值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到以前的狀態(能夠理解爲動畫執行完成後移除)
// kCAFillModeForwards 當動畫結束後,layer會一直保持着動畫最後的狀態與CABasicAnimation的removedOnCompletion結合使用
// kCAFillModeBackwards 當在動畫開始前,你只要把layer加入到一個動畫中,layer便當即進入動畫的初始狀態並等待動畫開始.你能夠這樣設定測試代碼,延遲3秒讓動畫開始,只要動畫被加入了layer,layer便處於動畫初始狀態
// pointLayer.fillMode = kCAFillModeBackwards;//是針對動畫的,決定當前對象在非active時間段的行爲.好比動畫開始以前,動畫結束以後的狀態
pointLayer.fillRule = kCAFillRuleEvenOdd;//對於兩個path有重疊部分,取其非交集。好比一個矩形中有一個圓,則填充顏色的區域是這兩個的非交集部分
// kCALineCapButt 直角
// kCALineCapRound 圓角
// kCALineCapSquare 與kCGLineCapButt是同樣的,可是比kCGLineCapButt長一點
pointLayer.lineCap = kCALineCapRound;//當線條是單獨的沒有與其餘線鏈接的時候,此時線頭的形狀
// kCALineJoinMiter 正常鏈接
// kCALineJoinRound 圓角
// kCALineJoinBevel 成斜角,是一條斜線
// pointLayer.lineJoin = kCALineJoinRound;//當線條與其餘線有鏈接的時候,鏈接處最外側線的顯示方式
pointLayer.fillColor = [UIColor clearColor].CGColor;//填充顏色。這裏由於是遮罩層,因此設置爲無顏色,則這部分不會顯示出來
pointLayer.lineWidth = 10;
CASpringAnimation *anim2 = [CASpringAnimation animationWithKeyPath:@"strokeEnd"];//9.0以後纔有的阻尼回彈動畫
anim2.fromValue = @0;
anim2.toValue = @1;
anim2.duration = 2;
anim2.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim2.damping = 8;//阻尼係數,值越大中止的越快
anim2.stiffness =100;//剛度係數(勁度係數/彈性係數),剛度係數越大,形變產生的力就越大,運動越快
anim2.mass = 2;//質量,影響圖層運動時的彈簧慣性,質量越大,彈簧拉伸和壓縮的幅度越大
//initialVelocity:
// 初始速率,動畫視圖的初始速度大小
// 速率爲正數時,速度方向與運動方向一致,速率爲負數時,速度方向與運動方向相反
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame =CGRectMake(10, 10, 190, 190);
UIColor *middleColor = [UIColor blueColor];
NSArray *colors = @[
(__bridge id)[UIColor redColor].CGColor,
(__bridge id)middleColor.CGColor,
];
gradientLayer.colors = colors;
gradientLayer.startPoint = CGPointMake(0.5, 0.5);
gradientLayer.endPoint = CGPointMake(0.5, 1);
gradientLayer.mask = pointLayer;//設置漸變層的遮罩層爲咱們前邊畫的半弧,則只會顯示板湖那部分區域
[self.view.layer addSublayer:gradientLayer];
[pointLayer addAnimation:anim2 forKey:@"animal"];
複製代碼
歡迎你們star來支持哦 Github源碼動畫
FlyOceanFishspa