iOS動畫:CAKeyframeAnimation

網(wǎng)絡(luò)中Core Animation類的繼承關(guān)系圖
CAAnimation繼承關(guān)系圖.png

屬性簡介

@interface CAKeyframeAnimation : CAPropertyAnimation
/* 提供關(guān)鍵幀數(shù)據(jù)的數(shù)組,數(shù)組中的每一個值都對應(yīng)一個關(guān)鍵幀旗笔。根據(jù)動畫類型(keyPath)的不同 彪置,
值的類型不同*/
@property(nullable, copy) NSArray *values;
/*基于點(diǎn)的屬性的路徑,即動畫屬性類型為CGPoint。如: position换团、anchorPoint悉稠、transform.translation等
如果為此屬性指定非空值,則會忽略values屬性*/
@property(nullable) CGPathRef path;
/* keyTimes的值與values中的值一一對應(yīng)指定關(guān)鍵幀在動畫中的時間點(diǎn)艘包,取值范圍為[0,1]的猛。當(dāng)keyTimes沒有設(shè)置的時候,
各個關(guān)鍵幀的時間是平分的*/
@property(nullable, copy) NSArray*keyTimes;
/*指定每個關(guān)鍵幀之間的動畫緩沖效果,timingFunctions.count = keyTimes.count-1*/
@property(nullable, copy) NSArray*timingFunctions;
/*關(guān)鍵幀間插值計算模式*/
@property(copy) NSString *calculationMode;
/*針對cubic 計算模式的動畫想虎,這些屬性提供對插值方案的控制卦尊。每個*關(guān)鍵幀都可以具有與之相關(guān)的
張力、連續(xù)性和偏差值舌厨,這些值的范圍在[-1,1]內(nèi)(這定義了Kochanek-*Bartels樣條岂却,見http://en.wikipedia.org/wiki/Kochanek-Bartels_spline)。

*tensionValues控制曲線的“緊密度”(正值更緊,負(fù)值更圓)躏哩。
*continuityValues控制段的連接方式(正值表示銳角署浩,負(fù)值表示倒角)。
*biasValues定義曲線發(fā)生的位置(正值在控制點(diǎn)之前移動曲線扫尺,負(fù)值在控制點(diǎn)之后移動它)筋栋。

*每個數(shù)組中的第一個值定義第一個控制點(diǎn)的切線的行為,第二個值控*制第二個點(diǎn)的切線正驻,依此類推弊攘。任何未指定的值都默認(rèn)為零
 *(如果未指定,則給出Catmull-Rom樣條曲線)姑曙。 
*/
@property(nullable, copy) NSArray*tensionValues;
@property(nullable, copy) NSArray*continuityValues;
@property(nullable, copy) NSArray *biasValues;

/*定義沿路徑動畫的對象是否旋轉(zhuǎn)以匹配路徑切線*/
@property(nullable, copy) NSString *rotationMode;

@end

關(guān)鍵幀動畫其實(shí)通過一組動畫類型的值(或者一個指定的路徑)和這些值對應(yīng)的時間節(jié)點(diǎn)以及各時間節(jié)點(diǎn)的過渡方式來控制顯示的動畫襟交。關(guān)鍵幀動畫可以通過path屬性和values屬性來設(shè)置動畫的關(guān)鍵幀。

通過path設(shè)置動畫

1.1 path只能控制CGPoint類型的動畫屬性伤靠。如position捣域、anchorPoint、transform.translation等
1.2 創(chuàng)建路徑時所有的MoveTo醋界、LineTo竟宋、CurveTo等方法是定的點(diǎn)都組成了動畫的關(guān)鍵幀提完⌒畏模可以通過keyTimes屬性賦值來控制關(guān)鍵幀的時間點(diǎn),通過timingFunctions屬性控制關(guān)鍵幀間的動畫
來控制動畫的顯示徒欣。
1.3 path屬性的優(yōu)先級高于values屬性優(yōu)先級逐样。當(dāng)path被賦非空值時,values屬性的值將被忽略打肝。
1.4 貝塞爾曲線可視工具:
http://yisibl.github.io/cubic-bezier/#.99,.01,1,.49

- (void)setPathAnimation
{
    CGMutablePathRef path = CGPathCreateMutable();
    //第一個關(guān)鍵幀  -100脂新,-100
    CGPathMoveToPoint(path, NULL, -100, -100);
    //第二個關(guān)鍵幀  100,-100
    CGPathAddLineToPoint(path, NULL, 100, -100);
    //第三個關(guān)鍵幀  100粗梭,100
    CGPathAddLineToPoint(path, NULL, 100, 100);
    //第四個關(guān)鍵幀  -100争便,100
    CGPathAddLineToPoint(path, NULL, -100, 100);
    //第五個關(guān)鍵幀  -100,-100
    CGPathAddLineToPoint(path, NULL, -100, -100);
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"transform.translation";
    animation.path = path;
    animation.duration = 4;
    animation.keyTimes = @[@(0),@(0.1),@(0.5),@(0.75),@(1)];
    animation.timingFunctions = @[[CAMediaTimingFunction functionWithControlPoints:1 :0.5 :0.5 :0.5],
                                  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
                                  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
                                  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
    //動畫結(jié)束后保持動畫最后的狀態(tài)断医,兩個屬性需配合使用
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    
    CGPathRelease(path);
    [self.layer addAnimation:animation forKey:@""];
}

通過values設(shè)置動畫

2.1 values指定了一組離散的關(guān)鍵幀滞乙,這些關(guān)鍵幀之間的需要通過插值來進(jìn)行過渡。這些插值計算方式calculationMode設(shè)置鉴嗤。
2.2 網(wǎng)上看到有說calculationMode適用于anchorPoint 和 position等坐標(biāo)點(diǎn)類型的屬性斩启,在查閱官方文檔及代碼測試,這種說法并不成立醉锅。calculationMode的插值計算方式同樣適用于backgroundColor兔簇、opacity等非坐標(biāo)點(diǎn)類型的動畫屬性

關(guān)鍵字 屬性
kCAAnimationLinear calculationMode的默認(rèn)值,關(guān)鍵幀之間直接直線相連進(jìn)行插值計算
kCAAnimationDiscrete 離散的,就是不進(jìn)行插值計算,所有關(guān)鍵幀直接逐個進(jìn)行顯示。values數(shù)組長度比keyTimes數(shù)組長度小1,每一個keyTime對表示當(dāng)前關(guān)鍵幀的起始時間和下一關(guān)鍵幀的起始時間垄琐,在keyTime對的時間內(nèi)边酒,物體停留在當(dāng)前關(guān)鍵幀指定的位置
kCAAnimationPaced 插入線性關(guān)鍵幀,動畫以恒定速度運(yùn)行狸窘。同時忽略keyTimes和timingFunctions設(shè)置
kCAAnimationCubic 對關(guān)鍵幀為進(jìn)行圓滑曲線相連后插值計算,對于曲線的形狀還可以通過tensionValues, continuityValues, biasValues來進(jìn)行自定義調(diào)整,這里的數(shù)學(xué)原理是Kochanek–Bartels spline,這里的主要目的是使得運(yùn)行的軌跡變得圓滑;
kCAAnimationCubicPaced 看這個名字就知道和kCAAnimationCubic有一定聯(lián)系,其實(shí)就是在kCAAnimationCubic的基礎(chǔ)上使得動畫運(yùn)行變得均勻,就是系統(tǒng)時間內(nèi)運(yùn)動的距離相同,此時keyTimes以及timingFunctions也是無效的甚纲。對于曲線的形狀也可以使用tensionValues,continuityValues,biasValues來進(jìn)行調(diào)整
- (void)setValuesAnimation
{
    CGPoint center = self.view.center;
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    animation.duration = 4;
    animation.repeatCount = CGFLOAT_MAX;
    animation.delegate = self;
    
    //    計算方式1: kCAAnimationLinear 直線相連進(jìn)行插值計算
    animation.calculationMode = kCAAnimationLinear;
    animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
                         [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
                         [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
                         [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
                         [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
    animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)];
    animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
                                  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
                                  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
    
    //    計算方式2: kCAAnimationDiscrete。 無插值計算values.count = keyTimes.count-1;
    //    animation.calculationMode = kCAAnimationDiscrete;
    //    animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],   //關(guān)鍵幀1開始時間0*duration=第0s
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],   //關(guān)鍵幀2開始時間0.25*duration=第1s
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],   //關(guān)鍵幀3開始時間0.5*duration=第2s
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)]];  //關(guān)鍵幀4開始時間0.75*duration=第3s 在第4秒動畫結(jié)束
    //    animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)];
    
    //    計算方式3: kCAAnimationPaced朦前。 關(guān)鍵幀間直線相連進(jìn)行插值計算介杆,動畫以恒定速度運(yùn)行,忽略keyTimes韭寸、timingFunctions;
    //    animation.calculationMode = kCAAnimationPaced;
    //    animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
    
    //    計算方式4: kCAAnimationCubic春哨。 關(guān)鍵幀間曲線相連進(jìn)行插值計算
    //    animation.calculationMode = kCAAnimationCubic;
    //    animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
    //    //然而知道該如何精確操作
    //    animation.tensionValues = @[@(1),@(0),@(0),@(0),@(0)];
    //    animation.continuityValues = @[@(-1),@(1),@(-1),@(1),@(-1)];
    //    animation.biasValues= @[@(1),@(1),@(1),@(1),@(1)];
    
    //    計算方式5: kCAAnimationCubic。關(guān)鍵幀間曲線相連進(jìn)行插值計算恩伺,動畫以恒定速度運(yùn)行赴背,忽略keyTimes、timingFunctions;
    //   animation.calculationMode = kCAAnimationCubicPaced;
    //    animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
    //                          [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
    //    animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)];
    //    animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
    //                                   [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
    //                                   [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
    //                                   [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
    //    //然而知道該如何精確操作
    //    animation.tensionValues = @[@(1),@(0),@(0),@(0),@(0)];
    //    animation.continuityValues = @[@(-1),@(1),@(-1),@(1),@(-1)];
    //    animation.biasValues= @[@(1),@(1),@(1),@(1),@(1)];
    
    [self.layer addAnimation:animation forKey:@""];
    
    if (!_displayLink) {
        [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
}

如有大神碰巧路過晶渠,發(fā)現(xiàn)問題請進(jìn)行指正

demo地址:
https://gitee.com/dbmxl/KeyframeAnimation

參考文章:
http://www.iosxxx.com/blog/2015-11-01-coreanimationdong-hua-ru-men.html
http://www.reibang.com/p/22333040616e

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凰荚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子褒脯,更是在濱河造成了極大的恐慌便瑟,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件番川,死亡現(xiàn)場離奇詭異到涂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颁督,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門践啄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沉御,你說我怎么就攤上這事屿讽。” “怎么了吠裆?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵伐谈,是天一觀的道長。 經(jīng)常有香客問我硫痰,道長衩婚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任效斑,我火速辦了婚禮非春,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己奇昙,他們只是感情好护侮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著储耐,像睡著了一般羊初。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上什湘,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天长赞,我揣著相機(jī)與錄音,去河邊找鬼闽撤。 笑死得哆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的哟旗。 我是一名探鬼主播贩据,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闸餐!你這毒婦竟也來了饱亮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤舍沙,失蹤者是張志新(化名)和其女友劉穎近上,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體场勤,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戈锻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年歼跟,在試婚紗的時候發(fā)現(xiàn)自己被綠了和媳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡哈街,死狀恐怖留瞳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情骚秦,我是刑警寧澤她倘,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站作箍,受9級特大地震影響硬梁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胞得,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一荧止、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦跃巡、人聲如沸危号。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽外莲。三九已至,卻和暖如春兔朦,著一層夾襖步出監(jiān)牢的瞬間偷线,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工沽甥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淋昭,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓安接,卻偏偏與公主長得像翔忽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子歇式,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,148評論 3 23
  • 在iOS中隨處都可以看到絢麗的動畫效果胡野,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺ios動畫全貌瞳腌。在這里你可以看...
    每天刷兩次牙閱讀 8,485評論 6 30
  • 在iOS實(shí)際開發(fā)中常用的動畫無非是以下四種:UIView動畫绞铃,核心動畫,幀動畫嫂侍,自定義轉(zhuǎn)場動畫儿捧。 1.UIView...
    請叫我周小帥閱讀 3,092評論 1 23
  • 在iOS中隨處都可以看到絢麗的動畫效果冷离,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺iOS動畫全貌纯命。在這里你可以看...
    F麥子閱讀 5,110評論 5 13
  • 概覽 在iOS中隨處都可以看到絢麗的動畫效果西剥,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜,今天將帶大家一窺iOS動畫全貌亿汞。在這里你...
    Yiart閱讀 3,810評論 3 34