? ? ? 核心動(dòng)畫(huà),即Core Animation桥滨,是Apple封裝的一組非常好用且強(qiáng)大的動(dòng)畫(huà)API窝爪。它直接作用于Layer層弛车,通過(guò) - (void)addAnimation:(CAAnimation*)anim forKey:(nullableNSString*)key ,即可讓動(dòng)畫(huà)生效蒲每。
? ? ? ?創(chuàng)建核心動(dòng)畫(huà)纷跛,使用的是CAAnimation的子類,分別是基礎(chǔ)動(dòng)畫(huà)(CABasicAnimation)邀杏,關(guān)鍵幀動(dòng)畫(huà)(CAKeyframeAnimation)贫奠,轉(zhuǎn)場(chǎng)動(dòng)畫(huà)(CATransition)和組動(dòng)畫(huà)(CAAnimationGroup)。我做了個(gè)他們之間的關(guān)系草圖如下淮阐。
? ? ? CAAnimationDelegate是核心動(dòng)畫(huà)的代理叮阅,通過(guò)其可以在動(dòng)畫(huà)開(kāi)始與結(jié)束階段進(jìn)行一些操作刁品,不過(guò)需要注意的是在iOS9以前CAAnimationDelegate是CAAnimation的類別泣特,之后才是代理,且為強(qiáng)引用挑随。因此使用CAAnimationDelegate需判斷當(dāng)前系統(tǒng)版本状您,并且在當(dāng)前頁(yè)面dealloc之前需先動(dòng)畫(huà)移除,否則會(huì)出現(xiàn)無(wú)法釋放的內(nèi)存問(wèn)題兜挨。
? 下圖為我寫(xiě)過(guò)的一個(gè)小動(dòng)畫(huà)膏孟,分析一下其中使用的動(dòng)畫(huà)來(lái)簡(jiǎn)單介紹一下核心動(dòng)畫(huà)。
1拌汇、CABasicAnimation基礎(chǔ)動(dòng)畫(huà)
? ? ? ? GIF圖中柒桑,血量彈性變化,猴子轉(zhuǎn)身以及受傷抖動(dòng)動(dòng)畫(huà)都都使用了基礎(chǔ)動(dòng)畫(huà)噪舀。受傷抖動(dòng)動(dòng)畫(huà)的代碼如下魁淳,
CABasicAnimation*Animation = [CABasicAnimationanimationWithKeyPath:@"position"];
Animation.fromValue= [NSValuevalueWithCGPoint:CGPointMake(pet.centerX, pet.centerY)];
Animation.toValue= [NSValuevalueWithCGPoint:CGPointMake(pet.centerX+5, pet.centerY)];
Animation.autoreverses=YES;
//Animation.beginTime=CACurrentMediaTime()+0.8;
//Animation.removedOnCompletion=NO;
Animation.fillMode=kCAFillModeBackwards;
Animation.repeatCount=10;
Animation.duration=0.02;//一次時(shí)間
屬性解析
? ? ? CABasicAnimationanimationWithKeyPath? ? 動(dòng)畫(huà)路徑,告訴系統(tǒng)需要執(zhí)行的動(dòng)畫(huà)類型 与倡。position為位置界逛,而猴子旋轉(zhuǎn)路徑則為transform.rotation.z。
? ? ? ?fromValue纺座,toValue ? ?動(dòng)畫(huà)的起始值與終止值
? ? ? ?autoreverses ? ?動(dòng)畫(huà)是否沿原路徑返回
? ? ? fillMode? 分kCAFillModeForwards息拜,kCAFillModeBackwards,kCAFillModeBoth净响,kCAFillModeRemoved四中模式少欺。當(dāng)你設(shè)置removedOnCompletion值為NO時(shí),kCAFillModeForwards可以讓當(dāng)前視圖保持在動(dòng)畫(huà)最后的位置馋贤;當(dāng)你設(shè)置了延遲執(zhí)行時(shí)(beginTime)赞别,kCAFillModeBackwards會(huì)在代碼執(zhí)行時(shí),使layer層進(jìn)入動(dòng)畫(huà)開(kāi)始階段的位置掸掸,而結(jié)束后會(huì)返回layer本身位置氯庆;kCAFillModeBoth就很好理解了蹭秋,如果removedOnCompletion = NO那layer會(huì)在動(dòng)畫(huà)開(kāi)始之前就會(huì)迅速進(jìn)入動(dòng)畫(huà)的初始位置并在執(zhí)行完動(dòng)畫(huà)后停在動(dòng)畫(huà)結(jié)束的位置,如果removedOnCompletion = YES那layer會(huì)在動(dòng)畫(huà)開(kāi)始之前就會(huì)迅速進(jìn)入動(dòng)畫(huà)的初始位置并在執(zhí)行完動(dòng)畫(huà)后迅速返回到layer的本身位置堤撵。
? ? ? ?repeatCount ? 重復(fù)次數(shù)
? ? ? ? duration 動(dòng)畫(huà)時(shí)間
血量彈性變化仁讨,使用的是基礎(chǔ)動(dòng)畫(huà)的子類CASpringAnimation。它有幾個(gè)屬性实昨,分別是
mass洞豁,對(duì)象質(zhì)量質(zhì)量越大彈性越大需要的動(dòng)畫(huà)時(shí)間越長(zhǎng)。
stiffness荒给,剛度系數(shù)丈挟,剛度系數(shù)越大,產(chǎn)生形變的力就越大志电,運(yùn)動(dòng)越快曙咽。
damping,阻尼系數(shù)阻止彈簧伸縮的系數(shù)阻尼系數(shù)越大挑辆,停止越快例朱。時(shí)間越短。
initialVelocity鱼蝉,初始速度洒嗤,正負(fù)代表方向,數(shù)值代表大小魁亦。
2渔隶,關(guān)鍵幀動(dòng)畫(huà)與組動(dòng)畫(huà)
GIF圖中,香蕉茄子的飛行動(dòng)畫(huà)使用的為組動(dòng)畫(huà)洁奈,組動(dòng)畫(huà)中包含了兩個(gè)關(guān)鍵幀動(dòng)畫(huà)和一個(gè)旋轉(zhuǎn)組動(dòng)畫(huà)间唉。CAAnimationGroup的animations屬性可以將動(dòng)畫(huà)放到數(shù)組中,同時(shí)執(zhí)行睬魂。
其中物品的飛行過(guò)程中的大小變化代碼
CGFloatfrom3DScale =1+arc4random() %10*0.1;
CGFloatto3DScale =1;
CAKeyframeAnimation*Animation = [CAKeyframeAnimationanimationWithKeyPath:@"transform"];
Animation.values=@[[NSValuevalueWithCATransform3D:CATransform3DMakeScale(from3DScale, from3DScale, from3DScale)], [NSValuevalueWithCATransform3D:CATransform3DMakeScale(to3DScale, to3DScale, to3DScale)]];
Animation.timingFunctions=@[[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseIn]];
? ? ? ? ? 關(guān)鍵幀動(dòng)畫(huà)相對(duì)于基礎(chǔ)動(dòng)畫(huà)的區(qū)別是终吼,CABasicAnimation只能從一個(gè)數(shù)值(fromValue)變到另一個(gè)數(shù)值(toValue),而CAKeyframeAnimation會(huì)使用一個(gè)NSArray保存這些數(shù)值氯哮。timingFunctions則是動(dòng)畫(huà)的節(jié)奏际跪。
飛行動(dòng)畫(huà)代碼
CGMutablePathRefpathOne =CGPathCreateMutable();
CGPathMoveToPoint(pathOne,NULL, start.x, start.y);
CGPathAddQuadCurveToPoint(pathOne,NULL, start.x, -1, end.x, end.y);
CAKeyframeAnimation*animationOne = [CAKeyframeAnimationanimationWithKeyPath:@"position"];
[animationOnesetPath:pathOne];
animationOne.duration=1.2;
animationOne.fillMode=kCAFillModeForwards;
animationOne.removedOnCompletion=NO;
CFRelease(pathOne);
pathOne =nil;
? ? ? ? 飛行路徑的path可以通過(guò)CGPathRef\CGMutablePathRef繪制,讓層跟著路徑移動(dòng)喉钢。path只對(duì)CALayer的anchorPoint和position起作用姆打。如果你設(shè)置了path,那么values將被忽略肠虽。需要注意的是幔戏,需要手動(dòng)繪制的路徑釋放。若想細(xì)致控制動(dòng)畫(huà)税课,還可設(shè)置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í)間是平分的陆馁。
3,轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
? ? ? ? ?此GIF中沒(méi)有用到合愈,它能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫(huà)效果叮贩。其實(shí)UINavigationController就是通過(guò)CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫(huà)效果。說(shuō)明一下它的幾個(gè)屬性佛析。
type:動(dòng)畫(huà)過(guò)渡類型
subtype:動(dòng)畫(huà)過(guò)渡方向
startProgress:動(dòng)畫(huà)起點(diǎn)(在整體動(dòng)畫(huà)的百分比)
endProgress:動(dòng)畫(huà)終點(diǎn)(在整體動(dòng)畫(huà)的百分比)