關于 Core Animation
Core Animation是一組非常強大的動畫處理API,使用它能做出很多優雅的動畫效果。能用的動畫類有4個子類:CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup
開發步驟:
- 初始化一個動畫對象(CAAnimation)并設置一些動畫相關屬性.
- 添加動畫對象到層(CALayer)中,開始執行動畫.
CALayer中很多屬性都可以通過CAAnimation實現動畫效果, 包括opacity, position, transform, bounds, contents等,具體可以在API文檔中查找
通過調用CALayer的addAnimation:forKey:增加動畫到層(CALayer)中,這樣就能觸發動畫了.通過調用removeAnimationForKey:可以停止層中的動畫.
注:Core Animation的動畫執行過程都是在后臺操作的,不會阻塞主線程.
創建動畫時你可能用到的屬性
屬性 | 解讀
----|------|----
Autoreverses | 設定這個屬性為 YES 時,在它到達目的地之后,動畫的返回到開始的值,代替了直接跳轉到開始的值,過渡平滑
Duration |設定開始值到結束值花費的時間。期間會被速度的屬性所影響
RemovedOnCompletion | 這個屬性默認為 YES,在指定的時間段完成后,動畫就自動的從層上移除了。
FillMode | 這個屬性一般和 RemovedOnCompletion 配合使用,保持動畫狀態。其中kCAFillModeForwards 當動畫結束后,layer會一直保持著動畫最后的狀態.此時將RemovedOnCompletion設為NO
Speed | 默認的值為 1.0.如果你改變這個值為 2.0,動畫會用 2 倍的速度播放。這樣的影響就是使持續時間減半。如果你指定的持續時間為 6 秒,速度為 2.0,動畫就會播放 3 秒鐘即一半的持續時間。
RepeatCount | 默認的是 0,動畫只會播放一次。如果指定一個無限大的重復次數,使用 MAXFLOAT 。這個不應該和 repeatDration 屬性一塊使用
RepeatDuration | 這個屬性指定了動畫應該被重復多久。動畫會一直重復,直到設定的時間用完。同上它不應該和 repeatCount 一起使用
FromValue | 設置動畫的初始值
ToValue | 設置動畫的到達值
TimingFunction | 控制動畫運行的節奏. kCAMediaTimingFunctionLinear(線性):勻速,給你一個相對靜態的感覺 kCAMediaTimingFunctionEaseIn(漸進):動畫緩慢進入,然后加速離開 kCAMediaTimingFunctionEaseOut(漸出):動畫全速進入,然后減速的到達目的地 kCAMediaTimingFunctionEaseInEaseOut(漸進漸出):動畫緩慢的進入,中間加速,然后減速的到達目的地。這個是默認的動畫行為。
BeginTime | 可以用來設置動畫延遲執行時間,若想延遲1s,就設置為CACurrentMediaTime()+1,CACurrentMediaTime()為圖層的當前時間
巧妙的運用這些可以屬性實現很棒的動畫效果,比如下面:用CABasicAnimation實現的動畫
CABasicAnimation動畫
簡單的呼吸和搖擺動畫
簡單的代碼
1.呼吸動畫
CABasicAnimation *animation =[CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = [NSNumber numberWithFloat:1.0f];
animation.toValue = [NSNumber numberWithFloat:0.0f];
animation.autoreverses = YES; //回退動畫(動畫可逆,即循環)
animation.duration = 1.0f;
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;//removedOnCompletion,fillMode配合使用保持動畫完成效果
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[self.alphaTagButton.layer addAnimation:animation forKey:@"aAlpha"];
2.搖擺動畫
//設置旋轉原點
self.sharkTagButton.layer.anchorPoint = CGPointMake(0.5, 0);
CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
//角度轉弧度(這里用1,-1簡單處理一下)
rotationAnimation.toValue = [NSNumber numberWithFloat:1];
rotationAnimation.fromValue = [NSNumber numberWithFloat:-1];
rotationAnimation.duration = 1.0f;
rotationAnimation.repeatCount = MAXFLOAT;
rotationAnimation.removedOnCompletion = NO;
rotationAnimation.autoreverses = YES;
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
rotationAnimation.fillMode = kCAFillModeForwards;
[self.sharkTagButton.layer addAnimation:rotationAnimation forKey:@"revItUpAnimation"];
陀螺儀&加速儀的動畫
ps:好吧 這個屬于亂入,和上面的搖擺動畫差不多的效果,只是這個是手動的 哈哈
3、陀螺儀&加速儀的動畫
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 1.0f/100.0f; //1秒100次
self.sharkTagButton.layer.anchorPoint = CGPointMake(0.5, 0);
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
if(fabs(motion.attitude.roll)<1.0f)
{
[UIView animateWithDuration:0.6 animations:^{
self.sharkTagButton.layer.transform = CATransform3DMakeRotation(-(motion.attitude.roll), 0, 0, 1);
}];
}else if (fabs(motion.attitude.roll)<1.5f)
{
[UIView animateWithDuration:0.6 animations:^{
int s;
if (motion.attitude.roll>0)
{
s=-1;
}else
{
s = 1;
}
self.sharkTagButton.layer.transform = CATransform3DMakeRotation(s*M_PI_2, 0, 0, 1);
}];
}
if ((motion.attitude.pitch)<0)
{
[UIView animateWithDuration:0.6 animations:^{
self.sharkTagButton.layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
}];
}
}];
Demo地址:
https://github.com/yongliangP/CABasicAnimationDemo
CATransition之簡單的轉場動畫
CAAnimation的子類,用于做轉場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。
屬性 | 解讀 |
---|---|
type | 動畫過渡類型 |
subtype | 動畫過渡方向 |
- 常用動畫類型:
type的值 | 解讀 | 對應常量 |
---|---|---|
fade | 淡入淡出 | kCATransitionFade |
push | 推擠 | kCATransitionPush |
reveal | 揭開 | kCATransitionReveal |
moveIn | 覆蓋 | kCATransitionMoveIn |
cube | 立方體 | 私有API |
suckEffect | 吮吸 | 私有API |
oglFlip | 翻轉 | 私有API |
rippleEffect | 波紋 | 私有API |
pageCurl | 反翻頁 | 私有API |
cameraIrisHollowOpen | 開鏡頭 | 私有API |
cameraIrisHollowClose | 關鏡頭 | 私有API |
注:私有API只能通過字符串使用哈
- 過渡方向參數:
subtype的值 | 解讀 |
---|---|
kCATransitionFromRight | 從右轉場 |
kCATransitionFromLeft | 從左轉場 |
kCATransitionFromBottom | 從下轉場 |
kCATransitionFromTop | 從上轉場 |
簡單的CATransition動畫
-(void)animationWithType:(NSString*)type
{
//- 創建一個轉場動畫:
CATransition *transition = [CATransition animation];
transition.repeatCount = 5;
// - 確定動畫類型:
transition.type = type;
// - 確定子類型(方向等)
transition.subtype = kCATransitionFromLeft;
// - 確定動畫時間
transition.duration = 1;
// - 添加動畫
[self.imageView.layer addAnimation:transition forKey:nil];
}
使用時只用傳你的想要的動畫類型就好,私有API只能通過字符串使用哈。
[self animationWithType:self.dataArray[indexPath.row]];
DEMO地址:https://github.com/yongliangP/CATransitionDemo
---20160908更新
CAKeyframeAnimation
先看圖,就是那個在跑的小圓球,為了方便,把動畫集成在了一個Demo里了
- 1 .簡單介紹
CAKeyframeAnimation是CApropertyAnimation的子類,跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值,是一種更靈活的動畫方式。
- 2 .屬性介紹
屬性 | 解讀 |
---|---|
values | NSArray對象,里面的元素稱為”關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀 |
path | 可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那么values將被忽略 |
keyTimes | 可以為對應的關鍵幀指定對應的時間點,其取值范圍為[0,1],keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的 |
- 3 .實現
- 3.1 values方式實現
-(void)setUpCAKeyframeAnimationUseValues
{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(kWindowWidth - 50, 50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(kWindowWidth - 50, kWindowHeight-50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(50, kWindowHeight-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
animation.values = @[value1,value2,value3,value4,value5];
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 6.0f;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.keyButton.layer addAnimation:animation forKey:@"values"];
}
- 3.2 path方式實現
-(void)setUpCAKeyframeAnimationUsePath
{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
CGMutablePathRef path = CGPathCreateMutable();
//矩形線路
CGPathAddRect(path, NULL, CGRectMake(50,50, kWindowWidth - 100,kWindowHeight - 100));
animation.path=path;
CGPathRelease(path);
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 10.0f;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.keyButton.layer addAnimation:animation forKey:@"path"];
}
- 3.3 keyTimes演示
-(void)setUpCAKeyframeAnimationUsekeyTimes
{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
// animation.keyPath = @"transform.translation.x";
animation.keyPath = @"position.x";
animation.values = @[@0, @20, @-20, @20, @0];
animation.keyTimes = @[ @0, @(1 / 6.0), @(3 / 6.0), @(5 / 6.0), @1 ];
animation.duration = 0.5;
animation.additive = YES;
[self.sharkTagButton.layer addAnimation:animation forKey:@"keyTimes"];
}
---20160921更新
CAAnimationGroup
看圖,就是那個下方的小長方形,簡單實現
動畫組,顧名思義就是動畫的組合,具體動畫可以參考上文,不同的腦洞會出現不同的化學反應。
簡單示例:
CABasicAnimation * animationScale = [CABasicAnimation animation];
animationScale.keyPath = @"transform.scale";
animationScale.toValue = @(0.1);
CABasicAnimation *animationRota = [CABasicAnimation animation];
animationRota.keyPath = @"transform.rotation";
animationRota.toValue = @(M_PI_2);
CAAnimationGroup * group = [[CAAnimationGroup alloc] init];
group.duration = 3.0;
group.fillMode = kCAFillModeForwards;
group.removedOnCompletion = NO;
group.repeatCount = MAXFLOAT;
group.animations = @[animationScale,animationRota];
[self.groupButton.layer addAnimation:group forKey:nil];
附:關于keyPath你可能用到的屬性
屬性 | 解讀 |
---|---|
transform.rotation.x | 圍繞x軸翻轉。y,z同理 參數:角度 |
transform.rotation | 默認圍繞z軸 |
transform.scale.x | x方向縮放。y,z同理 |
transform.scale | 所有方向縮放 |
transform.translation.x | x軸方向移動,參數:x軸上的坐標。y,z同理 |
transform.translation | 移動到的點 |
zPosition | 平面的位置 |
opacity | 透明度 |
backgroundColor | 背景顏色 參數:顏色 (id)[[UIColor redColor] CGColor] |
cornerRadius | layer圓角 |
borderWidth | 邊框寬度 |
bounds | 大小 參數:CGRect |
contents | 內容 參數:CGImage |
contentsRect | 可視內容 參數:CGRect 值是0~1之間的小數 |
position | 位置,效果和transform.rotation差不多 |
shadowColor | 陰影顏色 |
shadowOffset | 陰影偏移 |
shadowOpacity | 陰影透明度 |
shadowRadius | 陰影角度 |
照例放Demo
Demo地址:
https://github.com/yongliangP/CABasicAnimationDemo
如果你覺得對你有幫助請點喜歡哦,也可以關注我,每周至少一篇技術。
或者關注 我的專題 每周至少5篇更新,多謝支持哈。
(ps:核心動畫編程pdf中文版想要的可以私信我)