今天寫(xiě)Layer Animations是為了記錄自己學(xué)習(xí)的過(guò)程。如有想學(xué)習(xí)UI view Animation 的可以看看iOS動(dòng)畫(huà)之UIView動(dòng)畫(huà),IOS開(kāi)發(fā)-UIView之動(dòng)畫(huà)效果的實(shí)現(xiàn)方法(合集)
Core Animation是直接作用在CALayer上的(并非UIView上)非常強(qiáng)大的跨Mac OS X和iOS平臺(tái)的動(dòng)畫(huà)處理API罪治,Core Animation的動(dòng)畫(huà)執(zhí)行過(guò)程都是在后臺(tái)操作的,不會(huì)阻塞主線(xiàn)程乎澄。
核心動(dòng)畫(huà)繼承結(jié)構(gòu)
如上圖 ,我們能看出動(dòng)畫(huà)體協(xié)的結(jié)構(gòu)了测摔。
我們可以看到
CABasicAnimation
置济、CAkeyFrameanimation
都是繼承CAPropertyAnimation
,那他們倆有什么區(qū)別呢锋八?
詳解
- CABasicAnimation提供了最基礎(chǔ)的動(dòng)畫(huà)屬性設(shè)置浙于,是簡(jiǎn)單的keyframe動(dòng)畫(huà)性能。CABasicAnimation可以看做是一種CAKeyframeAnimation的簡(jiǎn)單動(dòng)畫(huà)挟纱,因?yàn)樗挥蓄^尾的關(guān)鍵幀(keyframe)羞酗。
- CAKeyframeAnimation提供了通用的keyframe動(dòng)畫(huà)功能層的屬性給我們使用,它允許我們?cè)O(shè)置一個(gè)特定的數(shù)組紊服,這個(gè)數(shù)組是動(dòng)畫(huà)在運(yùn)動(dòng)時(shí)的值檀轨。也就是說(shuō)胸竞,CAKeyframeAnimation支持動(dòng)畫(huà)的多個(gè)值設(shè)置。
我們可以說(shuō) CABasicAnimation
是對(duì)CAkeyFrameanimation
一個(gè)簡(jiǎn)單的封裝参萄。
下表是使用動(dòng)畫(huà)的基本屬性
屬性 | 說(shuō)明 |
---|---|
KeyPath | 動(dòng)畫(huà)變化的屬性(見(jiàn)圖2-1 卫枝、2-2) |
duration | 動(dòng)畫(huà)執(zhí)行的時(shí)長(zhǎng) |
repeatCount | 重復(fù)的次數(shù)。無(wú)限循環(huán)設(shè)置為 HUGE_VALF |
repeatDuration | 設(shè)置動(dòng)畫(huà)的時(shí)間讹挎。在該時(shí)間內(nèi)動(dòng)畫(huà)一直執(zhí)行剃盾,不計(jì)次數(shù)。 |
beginTime | 指定動(dòng)畫(huà)開(kāi)始的時(shí)間淤袜。從開(kāi)始延遲幾秒的話(huà),設(shè)置為【CACurrentMediaTime() + 秒數(shù)】 的方式 |
timingFunction | 速度控制函數(shù)衰伯,控制動(dòng)畫(huà)運(yùn)行的節(jié)奏 詳見(jiàn)(圖4) |
autoreverses | 動(dòng)畫(huà)結(jié)束時(shí)是否執(zhí)行逆動(dòng)畫(huà) |
fromValue | 起始值 |
toValue | 結(jié)束時(shí)的值(絕對(duì)坐標(biāo)) |
byValue | 相對(duì)起始值的改變量 |
speed | 動(dòng)畫(huà)的速度 |
removedOnCompletion | 默認(rèn)為YES铡羡,代表動(dòng)畫(huà)執(zhí)行完畢后就從圖層上移除,圖形會(huì)恢復(fù)到動(dòng)畫(huà)執(zhí)行前的狀態(tài)意鲸。如果想讓圖層保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)烦周,那就設(shè)置為NO,不過(guò)還要設(shè)置fillMode為kCAFillModeForwards |
fillMode | 決定當(dāng)前對(duì)象在非active時(shí)間段的行為怎顾。比如動(dòng)畫(huà)開(kāi)始之前或者動(dòng)畫(huà)結(jié)束之读慎,詳見(jiàn)“圖3” |
values | NSArray對(duì)象。里面的元素稱(chēng)為“關(guān)鍵幀”(keyframe)槐雾。動(dòng)畫(huà)對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi)夭委,依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀 |
keyTimes | 可以為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn),其取值范圍為0到1.0募强,例如keyAnima1.keyTimes = @[@0.0,@0.1,@0.5,@0.7,@1.0]株灸,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀。如果沒(méi)有設(shè)置keyTimes擎值,各個(gè)關(guān)鍵幀的時(shí)間是平分的慌烧,keyTimes 是和 values一起的。 |
path | 可以設(shè)置一個(gè)CGPathRef鸠儿、CGMutablePathRef屹蚊,讓圖層按照路徑軌跡移動(dòng)。path只對(duì)CALayer的anchorPoint和position起作用进每。如果設(shè)置了path汹粤,那么values將被忽略 |
delegate | 動(dòng)畫(huà)代理,動(dòng)畫(huà)開(kāi)始 和 動(dòng)畫(huà)完成(該代理是strong類(lèi)型可使用YYWeakProxy )self.animation.delegate = [YYWeakProxy proxyWithTarget:self];
|
以上圖片均來(lái)自網(wǎng)絡(luò)
CABasicAnimation示例代碼
CABasicAnimation * animation = [CABasicAnimation animation];
animation.keyPath = @"position";//KVC的方式來(lái)訪(fǎng)問(wèn)屬性
animation.fromValue =[NSValue valueWithCGPoint:CGPointMake(100, 100)];;//該屬性開(kāi)始的值
// animation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)];;//結(jié)束的值
animation.byValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)];
animation.duration = 2;//持續(xù)時(shí)間
animation.repeatCount = HUGE_VALF;//無(wú)限循環(huán)
animation.speed = 1;//速度
// animation.repeatDuration = 10;//在多久哪動(dòng)畫(huà)有效
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//結(jié)束函數(shù)
animation.autoreverses= YES;//回歸是否是動(dòng)畫(huà)形式
[_maskView.layer addAnimation:animation forKey:@"ad"];//添加動(dòng)畫(huà)
CAAnimationGroup的使用
此類(lèi)就是一個(gè)動(dòng)畫(huà)數(shù)組自己沒(méi)有執(zhí)行動(dòng)畫(huà)的能力田晚,就是來(lái)做組合動(dòng)畫(huà)玄括。
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.fromValue = @(self.maskView.center.y);
positionAnima.toValue = @(self.maskView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnima.fromValue = @(0);
transformAnima.toValue = @(M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[positionAnima,transformAnima];
[self.maskView.layer addAnimation:animaGroup forKey:@"Animation"];
CASpringAnimation阻尼動(dòng)畫(huà)
通俗的說(shuō)就是彈簧效果,使用起來(lái)很簡(jiǎn)單。
屬性 | 說(shuō)明 |
---|---|
mass | 這個(gè)屬性設(shè)置彈簧重物的質(zhì)量 會(huì)影響慣性 必須大于0 默認(rèn)為1 |
stiffness | 設(shè)置彈簧的剛度系數(shù)肉瓦,必須大于0 默認(rèn)為100 這個(gè)越大 則回彈越快 |
damping | 阻尼系數(shù) 默認(rèn)為10 必須大于0 這個(gè)值越大 回彈的幅度越小 |
initialVelocity | 初始速度 |
settlingDuration | 獲取動(dòng)畫(huà)停下來(lái)需要的時(shí)間 |
CATransition轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
屬性 | 說(shuō)明 |
---|---|
type | 指定預(yù)定義的過(guò)渡效果遭京。默認(rèn)為kCATransitionFade,如果指定了filter胃惜,那么該屬性無(wú)效。 |
subtype | 指定預(yù)定義的過(guò)渡方向哪雕。默認(rèn)為nil,如果指定了filter船殉,那么該屬性無(wú)效。 |
startProgress | 定義過(guò)度的開(kāi)始點(diǎn) |
endProgress | 定義過(guò)渡的結(jié)束點(diǎn).值必須大于或者等于開(kāi)始點(diǎn) |
filter | 為動(dòng)畫(huà)添加一個(gè)可選的濾鏡.如果指定斯嚎,那么指定的filter必須同時(shí)支持x和y利虫,否則該filter將不起作用。 |
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
CATransition *animation = [CATransition animation];
// //動(dòng)畫(huà)時(shí)間
animation.duration = 5.0f;
//display mode, slow at beginning and end
animation.timingFunction = UIViewAnimationCurveEaseInOut;
//在動(dòng)畫(huà)執(zhí)行完時(shí)是否被移除
animation.removedOnCompletion = NO;
animation.repeatCount = 100;
//過(guò)渡效果
animation.type = @"pageCurl";
//過(guò)渡方向
animation.subtype = kCATransitionFromRight;
animation.fillMode = kCAFillModeForwards;
//animation.filter = filter;
//動(dòng)畫(huà)停止(在整體動(dòng)畫(huà)的百分比).
animation.endProgress = 0.7;
[_maskView.layer addAnimation:animation forKey:nil];
加濾鏡轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
//將UIImage轉(zhuǎn)換成CIImage
CIImage *ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"白胡子.jpg"]];
//創(chuàng)建濾鏡
CIFilter *filter = [CIFilter filterWithName:@"CIPhotoEffectMono" keysAndValues:kCIInputImageKey, ciImage, nil];
//已有的值不改變堡僻,其他的設(shè)為默認(rèn)值
[filter setDefaults];
//獲取繪制上下文
CIContext *context = [CIContext contextWithOptions:nil];
//渲染并輸出CIImage
CIImage *outputImage = [filter outputImage];
//創(chuàng)建CGImage句柄
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
//獲取圖片
UIImage *image = [UIImage imageWithCGImage:cgImage];
//釋放CGImage句柄
CGImageRelease(cgImage);
self.maskView.image = image;
CATransition *animation = [CATransition animation];
// //動(dòng)畫(huà)時(shí)間
animation.duration = 5.0f;
//display mode, slow at beginning and end
animation.timingFunction = UIViewAnimationCurveEaseInOut;
//在動(dòng)畫(huà)執(zhí)行完時(shí)是否被移除
animation.removedOnCompletion = NO;
animation.repeatCount = 100;
//過(guò)渡效果
// animation.type = @"pageCurl";
// //過(guò)渡方向
// animation.subtype = kCATransitionFromRight;
// //暫時(shí)不知,感覺(jué)與Progress一起用的,如果不加,Progress好像沒(méi)有效果
// animation.fillMode = kCAFillModeForwards;
animation.filter = filter;
// //動(dòng)畫(huà)停止(在整體動(dòng)畫(huà)的百分比).
// animation.endProgress = 0.7;
[_maskView.layer addAnimation:animation forKey:nil];
過(guò)濾器必須實(shí)現(xiàn)‘inputImage’,‘inputTargetImage’和‘inputTime輸入鍵和“outputImage”輸出的關(guān)鍵糠惫。
CAKeyframeAnimation 關(guān)鍵幀動(dòng)畫(huà)
屬性 | 說(shuō)明 |
---|---|
values | 里面的元素稱(chēng)為”關(guān)鍵幀”(keyframe)。動(dòng)畫(huà)對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi)钉疫,依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀 |
path | 可以設(shè)置一個(gè)CGPathRef\CGMutablePathRef,讓層跟著路徑移動(dòng)硼讽。 |
keyTimes | 可以為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀.當(dāng)keyTimes沒(méi)有設(shè)置的時(shí)候,各個(gè)關(guān)鍵幀的時(shí)間是平分的。這個(gè)屬性的設(shè)定值要與calculationMode屬性相結(jié)合 |
calculationMode | 計(jì)算模式 |
timingFunctions | 可以為對(duì)應(yīng)的關(guān)鍵幀指定--速度控制函數(shù)牲阁,控制動(dòng)畫(huà)運(yùn)行的節(jié)奏 詳見(jiàn)(圖4) |
rotationMode | 旋轉(zhuǎn)模式 默認(rèn)nil 設(shè)置后可自動(dòng)旋轉(zhuǎn) |
tensionValues | 暫時(shí)不知怎么用 |
continuityValues | 暫時(shí)不只怎么用 |
biasValues | 暫時(shí)不只怎么用 |
The appropriate values in the keyTimes array are dependent on the calculationMode property.
- If the calculationMode is set to kCAAnimationLinear, the first value in the array must be 0.0 and the last value must be 1.0. Values are interpolated between the specified key times.
- If the calculationMode is set to kCAAnimationDiscrete, the first value in the array must be 0.0.
- If the calculationMode is set to kCAAnimationPaced or kCAAnimationCubicPaced, the keyTimes array is ignored固阁。
不知道怎么用等了解之后再來(lái)更新
kCAAnimationCubic對(duì)關(guān)鍵幀為坐標(biāo)點(diǎn)的關(guān)鍵幀進(jìn)行圓滑曲線(xiàn)相連后插值計(jì)算,曲線(xiàn)的形狀可以通過(guò)tensionValues,continuityValues,biasValues來(lái)進(jìn)行調(diào)整自定義,使得運(yùn)動(dòng)的軌跡變得圓滑;
用 path來(lái)繪制動(dòng)畫(huà)路徑
CGMutablePathRef
path = CGPathCreateMutable();
//將路徑的起點(diǎn)定位到 (50 120)
CGPathMoveToPoint(path,NULL,50.0,120.0);
//下面5行添加5條直線(xiàn)的路徑到path中
CGPathAddLineToPoint(path,
NULL, 60, 130);
CGPathAddLineToPoint(path,
NULL, 70, 140);
CGPathAddLineToPoint(path,
NULL, 80, 150);
CGPathAddLineToPoint(path,
NULL, 90, 160);
CGPathAddLineToPoint(path,
NULL, 100, 170);
//下面四行添加四條曲線(xiàn)路徑到path
CGPathAddCurveToPoint(path,NULL,50.0,275.0,150.0,275.0,70.0,120.0);
CGPathAddCurveToPoint(path,NULL,150.0,275.0,250.0,275.0,90.0,120.0);
CGPathAddCurveToPoint(path,NULL,250.0,275.0,350.0,275.0,110.0,120.0);
CGPathAddCurveToPoint(path,NULL,350.0,275.0,450.0,275.0,130.0,120.0);
CAKeyframeAnimation *KeyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
KeyframeAnimation.path = path;
KeyframeAnimation.duration = 5;
KeyframeAnimation.calculationMode = kCAAnimationCubic;
KeyframeAnimation.rotationMode = kCAAnimationRotateAuto;
// KeyframeAnimation.keyTimes
[_maskView.layer addAnimation:KeyframeAnimation forKey:nil];
values動(dòng)畫(huà)
CGPoint
p1=CGPointMake(50, 120);
CGPoint
p2=CGPointMake(80, 170);
CGPoint
p3=CGPointMake(30, 100);
CGPoint
p4=CGPointMake(100, 190);
CGPoint
p5=CGPointMake(200, 10);
NSArray
*values=[NSArray arrayWithObjects:[NSValue valueWithCGPoint:p1],[NSValue valueWithCGPoint:p2],[NSValue valueWithCGPoint:p3],[NSValue valueWithCGPoint:p4],[NSValue valueWithCGPoint:p5], nil];
CAKeyframeAnimation *KeyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// KeyframeAnimation.path = path;
KeyframeAnimation.values = values;
KeyframeAnimation.duration = 5;
KeyframeAnimation.calculationMode = kCAAnimationCubic;
KeyframeAnimation.rotationMode = kCAAnimationRotateAuto;
// KeyframeAnimation.keyTimes
[_maskView.layer addAnimation:KeyframeAnimation forKey:nil];