CoreAnimation基本介紹
CoreAnimation動(dòng)畫(huà)位于iOS框架的Media層
CoreAnimation動(dòng)畫(huà)實(shí)現(xiàn)需要添加QuartzCore.Framework
CoreAnimation基本上是Layer Animation
CoreAnimation分類(lèi)
隱式動(dòng)畫(huà):無(wú)需指定任何動(dòng)畫(huà)的類(lèi)型,僅僅改變一個(gè)屬性,然后CoreAnimation來(lái)決定
如何計(jì)時(shí)去做動(dòng)畫(huà)。
顯示動(dòng)畫(huà):對(duì)一些屬性做指定的自定義動(dòng)畫(huà),或創(chuàng)建非線性動(dòng)畫(huà),比如沿著任意一條曲線移動(dòng)。
CoreAnimation作用
與UIView動(dòng)畫(huà)相比,CoreAnimation能夠?qū)崿F(xiàn)更多復(fù)雜、好看、高效的動(dòng)畫(huà)效果。
陰影,圓角,帶顏色的邊框。
3D變化。
透明遮罩
多級(jí)非線性動(dòng)畫(huà)
CoreAnimation的三種動(dòng)畫(huà)
CABasicAnimation基本單一類(lèi)型的動(dòng)畫(huà),通過(guò)設(shè)定起始點(diǎn),終點(diǎn),時(shí)間,動(dòng)畫(huà)會(huì)沿著你這設(shè)定點(diǎn)進(jìn)行移動(dòng)。可以看做特殊的CAKeyFrameAnimation 。
CAKeyframeAnimation幀動(dòng)畫(huà)主要操作屬性有keyPath和values值組合Keyframe顧名思義就是關(guān)鍵點(diǎn)的frame,你可以通過(guò)設(shè)定CALayer的始點(diǎn)、中間關(guān)鍵點(diǎn)、終點(diǎn)的frame,時(shí)間,動(dòng)畫(huà)會(huì)沿你設(shè)定的軌跡進(jìn)行移動(dòng)。
CAAnimationGroup組合動(dòng)畫(huà) 操作屬性animations將CAAnimation類(lèi)型的動(dòng)畫(huà)加入數(shù)組,以FIFO隊(duì)列的方式執(zhí)行。
CATransition這個(gè)就是蘋(píng)果幫開(kāi)發(fā)者封裝好的一些動(dòng)畫(huà)
CABasicAnimation
三個(gè)重要的屬性
@property(nullable,strong)idfromValue;動(dòng)畫(huà)的效果變化的初始值@property(nullable,strong)idtoValue;動(dòng)畫(huà)效果變化的結(jié)束值(絕對(duì)值)@property(nullable,strong)idbyValue;動(dòng)畫(huà)效果變化的結(jié)束值(相對(duì)值)
這三個(gè)屬性必須要有一個(gè)有值,它們的值就是原來(lái)視圖的放大,旋轉(zhuǎn)等倍數(shù)或者角度。
fromValue和toValue不為空,動(dòng)畫(huà)的效果會(huì)從fromValue的值變化到toValue。
fromValue和byValue都不為空,動(dòng)畫(huà)的效果將會(huì)從fromValue變化到fromValue+byValue。
toValue和byValue都不為空,動(dòng)畫(huà)的效果將會(huì)從toValue-byValue變化到toValue。
只有fromValue的值不為空,動(dòng)畫(huà)的效果將會(huì)從fromValue的值變化到當(dāng)前的狀態(tài)。
只有toValue的值不為空,動(dòng)畫(huà)的效果將會(huì)從當(dāng)前狀態(tài)的值變化到toValue的值。
只有byValue的值不為空,動(dòng)畫(huà)的效果將會(huì)從當(dāng)前的值變化到(當(dāng)前狀態(tài)的值+byValue)的值。
想要實(shí)現(xiàn)不同的效果,最關(guān)鍵的地方在于CABasicAnimation對(duì)象的初始化方式中keyPath的設(shè)定。在iOS中有以下幾種不同的keyPath,代表著不同的效果:
transform.rotation.x//以x軸為中心旋轉(zhuǎn)transform.rotation.y//以y軸為中心旋轉(zhuǎn)transform.rotation.z//以z軸為中心旋轉(zhuǎn)transform.scale.x//縮放x軸方向transform.scale.y//縮放y軸方向transform.scale.z//縮放z軸方向,這個(gè)一般不會(huì)用到。transform.scale//x,y方向整體縮放,z方向沒(méi)看到效果。
下面我們來(lái)簡(jiǎn)單的做一個(gè)動(dòng)畫(huà)
- (void)springAnimation{? ? CABasicAnimation *base= [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];/*在動(dòng)畫(huà)結(jié)束之后是否讓動(dòng)畫(huà)回到原處,這個(gè)屬性的默認(rèn)值是YES(回到原處),此時(shí)*fillMode*是沒(méi)有作用的
如果設(shè)置為NO那么就需要設(shè)置一個(gè)*fillMode*屬性,就是動(dòng)畫(huà)結(jié)束之后的狀態(tài),如果不設(shè)置,動(dòng)畫(huà)也會(huì)回到原處。*/base.removedOnCompletion = NO;//動(dòng)畫(huà)結(jié)束之后狀態(tài)的設(shè)置base.fillMode = kCAFillModeForwards;base.fromValue = @(2);//動(dòng)畫(huà)時(shí)長(zhǎng)base.duration =10;//動(dòng)畫(huà)的重復(fù)次數(shù)base.repeatCount =100;//給base動(dòng)畫(huà)設(shè)置延時(shí)啟動(dòng)base.beginTime =2+ CACurrentMediaTime();//動(dòng)畫(huà)是否按原路徑返回base.autoreverses = YES;//將動(dòng)畫(huà)添加到layer層*forKey*是給動(dòng)畫(huà)添加一個(gè)標(biāo)記,方便刪除。[self.redView.layer addAnimation:baseforKey:@"basic"];}
刪除動(dòng)畫(huà)的方法
-(void)removeAnimationForKey:(NSString*)key;key:你需要?jiǎng)h除的動(dòng)畫(huà)的名稱(chēng)。這個(gè)方法就是你把動(dòng)畫(huà)添加到那個(gè)視圖的layer層上,就由那個(gè)視圖的layer來(lái)調(diào)用。-(void)removeAllAnimations;這個(gè)法是刪除這個(gè)視圖layer層上的所有動(dòng)畫(huà)。
在這里簡(jiǎn)單介紹一下fillMode
注意:fillMode這個(gè)屬性,必須要配合下面這個(gè)屬性來(lái)使用。這個(gè)屬性的默認(rèn)值是YES(回到原處),此時(shí)fillMode是沒(méi)有作用的如果設(shè)置為NO那么就需要設(shè)置一個(gè)fillMode屬性,就是動(dòng)畫(huà)結(jié)束之后的狀態(tài),如果不設(shè)置,動(dòng)畫(huà)也會(huì)回到原處。
base.removedOnCompletion=NO;
kCAFillModeRemoved這個(gè)是默認(rèn)值,也就是說(shuō)當(dāng)動(dòng)畫(huà)開(kāi)始前和動(dòng)畫(huà)結(jié)束后,動(dòng)畫(huà)對(duì)layer都沒(méi)有影響,動(dòng)畫(huà)結(jié)束后,layer會(huì)恢復(fù)到之前的狀態(tài) kCAFillModeForwards當(dāng)動(dòng)畫(huà)結(jié)束后,layer會(huì)一直保持著動(dòng)畫(huà)最后的狀態(tài) kCAFillModeBackwards這個(gè)和kCAFillModeForwards是相對(duì)的,就是在動(dòng)畫(huà)開(kāi)始前,你只要將動(dòng)畫(huà)加入了一個(gè)layer,layer便立即進(jìn)入動(dòng)畫(huà)的初始狀態(tài)并等待動(dòng)畫(huà)開(kāi)始.你可以這樣設(shè)定測(cè)試代碼,將一個(gè)動(dòng)畫(huà)加入一個(gè)layer的時(shí)候延遲5秒執(zhí)行.然后就會(huì)發(fā)現(xiàn)在動(dòng)畫(huà)沒(méi)有開(kāi)始的時(shí)候,只要?jiǎng)赢?huà)被加入了layer,layer便處于動(dòng)畫(huà)初始狀態(tài) kCAFillModeBoth理解了上面兩個(gè),這個(gè)就很好理解了,這個(gè)其實(shí)就是上面兩個(gè)的合成.動(dòng)畫(huà)加入后開(kāi)始之前,layer便處于動(dòng)畫(huà)初始狀態(tài),動(dòng)畫(huà)結(jié)束后layer保持動(dòng)畫(huà)最后的狀態(tài).
CAKeyframeAnimation
這個(gè)動(dòng)畫(huà)可以讓你在動(dòng)畫(huà)的一些關(guān)鍵的位置來(lái)改變動(dòng)畫(huà)的frame以此來(lái)達(dá)到我們想要的效果。
position是描述動(dòng)畫(huà)視圖的位置信息的,簡(jiǎn)單理解就是和視圖的中心點(diǎn)一樣,所以我們通過(guò)改變position屬性,就可以改變動(dòng)畫(huà)的位置。
與position相對(duì)應(yīng)得是錨點(diǎn)也就是anchorPoint,anchorPoint、position、frame這三者之間有著如下的關(guān)系。
position.x = frame.origin.x + anchorPoint.x * bounds.size.width; position.y = frame.origin.y + anchorPoint.y * bounds.size.height;
示例代碼:下面是讓一個(gè)視圖左右震動(dòng)的動(dòng)畫(huà)
CAKeyframeAnimation*keyFram = [CAKeyframeAnimationanimationWithKeyPath:@"position"];//layer最初的position值floatposition_x =self.redView.layer.position.x;floatposition_y =self.redView.layer.position.y;//layer向左晃動(dòng)的偏移量NSValue*leftValue = [NSValuevalueWithCGPoint:CGPointMake(position_x -30, position_y)];//layer的原始位置NSValue*originValue = [NSValuevalueWithCGPoint:CGPointMake(position_x, position_y)];//layer向右晃動(dòng)的偏移量NSValue*right = [NSValuevalueWithCGPoint:CGPointMake(position_x +30, position_y)];//添加每一幀的Value值[keyFram setValues:@[originValue,leftValue,originValue,right,originValue]];? ? keyFram.repeatCount=10;? ? keyFram.repeatDuration=1;//為layer層添加動(dòng)畫(huà)[self.redView.layeraddAnimation:keyFram forKey:@"aaa"];
CAAnimationGroup
CAAnimationGroup是一個(gè)組合動(dòng)畫(huà),所謂的組合動(dòng)畫(huà)就是將多個(gè)動(dòng)畫(huà)組合到一起讓它產(chǎn)生很炫酷的效果。
注意:所有的組合動(dòng)畫(huà),它的延遲啟動(dòng),重復(fù)次數(shù)等屬性,同一在組里面設(shè)置,不要在單一的動(dòng)畫(huà)里面設(shè)置,以免出現(xiàn)問(wèn)題。
第一步:初始化組合動(dòng)畫(huà)
CAAnimationGroup*group = [CAAnimationGroupanimation];
第二步創(chuàng)建至少兩個(gè)動(dòng)畫(huà)
CABasicAnimation*base = [CABasicAnimationanimationWithKeyPath:@"transform.rotation.z"];/*在動(dòng)畫(huà)結(jié)束之后是否讓動(dòng)畫(huà)回到原處,這個(gè)屬性的默認(rèn)值是YES(回到原處),此時(shí)*fillMode*是沒(méi)有作用的
如果設(shè)置為NO那么就需要設(shè)置一個(gè)*fillMode*屬性,就是動(dòng)畫(huà)結(jié)束之后的狀態(tài),如果不設(shè)置,動(dòng)畫(huà)也會(huì)回到原處。*/base.removedOnCompletion=NO;//動(dòng)畫(huà)結(jié)束之后狀態(tài)的設(shè)置base.fillMode= kCAFillModeForwards;? base.fromValue= @(M_PI);//動(dòng)畫(huà)是否按原路徑返回base.autoreverses=YES;/************************************************************************************************/CAKeyframeAnimation*keyFram = [CAKeyframeAnimationanimationWithKeyPath:@"position"];//layer最初的position值floatposition_x =self.redView.layer.position.x;floatposition_y =self.redView.layer.position.y;//layer向左晃動(dòng)的偏移量NSValue*leftValue = [NSValuevalueWithCGPoint:CGPointMake(position_x -50, position_y)];//layer的原始位置NSValue*originValue = [NSValuevalueWithCGPoint:CGPointMake(position_x, position_y)];//layer向右晃動(dòng)的偏移量NSValue*right = [NSValuevalueWithCGPoint:CGPointMake(position_x +50, position_y)];//添加每一幀的Value值[keyFram setValues:@[originValue,leftValue,originValue,right,originValue]];
第三步將得到的動(dòng)畫(huà)放入group中
group.animations = @[base,keyFram];//將group加到layer上group.repeatCount =100;group.repeatDuration =10;? [self.redView.layer addAnimation:groupforKey:@"group"];