級別:★★☆☆☆
標簽:「iOS CAKeyframeAnimation」「iOS 關鍵幀動畫」「CAKeyframeAnimation values」「CAKeyframeAnimation path」
作者: Xs·H
審校: QiShare團隊
最近的項目需求涉及到一些動畫效果。對于基本的動畫投队,可以使用QiShare之前分享過的CABasicAnimation實現(xiàn),而和路徑相關的動畫(例如圖1的折線動畫)可以使用CAKeyframeAnimation實現(xiàn)息楔。
CAKeyframeAnimation和CABasicAnimation都是CAPropertyAnimation的子類。CABasicAnimation可以控制動畫的起點(fromValue
)和終點(toValue
)圃泡,而CAKeyframeAnimation可以控制動畫的全過程。所以颇蜡,可以將CABasicAnimation理解成只關注起點和終點的CAKeyframeAnimation辆亏。
對比CABasicAnimation來說,CAKeyframeAnimation是通過控制動畫的“關鍵幀”和“步調(diào)”(關鍵幀執(zhí)行的時間)來控制動畫過程的缤弦。
一彻磁、CAKeyframeAnimation使用“values”或“path”屬性來控制動畫的關鍵幀
values:可選的NSArray對象,存放多個
value
累提,每個value
就是一個keyframe
(關鍵幀)磁浇。在動畫過程中,關鍵幀會依序顯示出來扯夭。
path:可選的CGPathRef對象交洗,指定動畫的路徑橡淑,可讓CALayer的anchorPoint
和position
按照路徑變化。除了“moveTo”之外置森,路徑中的每個點都是一個關鍵幀符糊。如果需要沿路徑勻速動畫,需要將calculationMode
屬性設置為paced
男娄。當path
非nil
時漾稀,values
屬性被覆蓋崭捍。
二啰脚、CAKeyframeAnimation使用“keyTimes”屬性來控制動畫的步調(diào)
keyTimes: 可選的NSArray對象,存放多個
keyTime
粒梦,每個keyTime
都是[0, 1]區(qū)間內(nèi)的浮點數(shù)所對應的NSNumber贮配,與values
中的關鍵幀一一對應,控制關鍵幀發(fā)生的時間泪勒。
PS:當values
被path
覆蓋時,keyTimes
作用于path
叼旋。(path
的優(yōu)先級較高)
三沦辙、使用CAKeyframeAnimation實現(xiàn)圖1的折線動畫效果
為了輔助分析動畫過程,我們?yōu)閯赢嫾由宪壽E(后文只分析動畫本身详民,不分析軌跡)陌兑,如圖2。
1) 像使用CABasicAnimation一樣初始化CAKeyframeAnimation的對象
// 初始化動畫
self.animation = [CAKeyframeAnimation animation];
self.animation.keyPath = @"position";
self.animation.delegate = self;
self.animation.duration = 5.0;
self.animation.repeatCount = 1.0;
self.animation.removedOnCompletion = NO;
self.animation.fillMode = kCAFillModeForwards;
self.animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
2) 使用“values”和“keyTimes”屬性設置動畫的關鍵幀和步調(diào)
// 設置動畫的關鍵幀數(shù)組
self.animation.values = @[[NSValue valueWithCGPoint:self.imageView.center],// 不能省略起點(1, 1)
[NSValue valueWithCGPoint:(CGPoint){self.squareSide * 2, self.squareSide * 1}],// 右移1格
[NSValue valueWithCGPoint:(CGPoint){self.squareSide * 2, self.squareSide * 5}],// 下移4格
[NSValue valueWithCGPoint:(CGPoint){self.squareSide * 5, self.squareSide * 5}],// 右移3格
[NSValue valueWithCGPoint:(CGPoint){self.squareSide * 5, self.squareSide * 7}]// 下移2格
];
// 設置動畫的步調(diào)
self.animation.keyTimes = @[@.0, @.1, @.5, @.8, @1.0];
// self.animation.calculationMode = kCAAnimationPaced;// 可以替代上面的keyTimes實現(xiàn)勻速效果
PS: 上述代碼中的
keyTimes
是根據(jù)values
的值進行設定的饿凛,以達到動畫勻速的效果涧窒。若不設置keyTimes
锭亏,動畫時長(duration
)將被平均分配給4段動畫。
3) 像使用CABasicAnimation一樣為layer添加動畫和移除動畫
if (start) {
[self.imageView.layer addAnimation:_animation forKey:@"animation"];// 執(zhí)行動畫
}
else {
[self.imageView.layer removeAnimationForKey:@"animation"];// 移除動畫
}
上面有介紹到呜象,path
屬性同樣可以設置動畫的關鍵幀,并且當path
不為nil
時會覆蓋values
恭陡。
所以,步驟2)可以替換為“path”
和“keyTimes”
的方式休玩。
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.imageView.center.x, self.imageView.center.y);
CGPathAddLineToPoint(path, NULL, self.squareSide * 2, self.squareSide * 1);// 右移1格
CGPathAddLineToPoint(path, NULL, self.squareSide * 2, self.squareSide * 5);// 下移4格
CGPathAddLineToPoint(path, NULL, self.squareSide * 5, self.squareSide * 5);// 右移3格
CGPathAddLineToPoint(path, NULL, self.squareSide * 5, self.squareSide * 7);// 下移2格
self.animation.keyTimes = @[@.0, @.1, @.5, @.8, @1.0];
// self.animation.calculationMode = kCAAnimationPaced;// 可以替代上面的keyTimes實現(xiàn)勻速效果
self.animation.path = path;
CGPathRelease(path);
四拴疤、使用CAKeyframeAnimation實現(xiàn)曲線動畫
CAKeyframeAnimation的values
和path
屬性具有強大的功能,尤其是path
呐矾,可以方便的制定自定義動畫路徑,比如圖3的橢圓動畫效果组橄。
使用path制定上述橢圓路徑的代碼如下:
CGRect drawRect = (CGRect){self.squareSide, self.squareSide, self.squareSide * 8, self.squareSide * 6};
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, drawRect);
self.animation.keyTimes = @[@.0, @.25, @0.5, @0.75, @1.0];
// self.animation.calculationMode = kCAAnimationPaced;
self.animation.path = path;
示例源碼可從GitHub的QiShare開源庫中獲取玉工。
了解更多iOS及相關新技術淘菩,請關注我們的公眾號:
關注我們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號)
推薦文章:
iOS 繪制漸變·基礎篇