在介紹CoreAnimation動畫前先簡單介紹一下UIKit動畫,大部分簡單的動畫都可以使用UIKit動畫實現,如果想實現更復雜的效果,則需要使用Core Animation了,Core Animation中包含了可以實現更為復雜的基礎動畫和關鍵幀動畫等等。UIKit動畫有兩種寫法,它不僅可以針對視圖還可以針對其它控件。
1:第一種寫法是利用屬性,結合beginAnimations、commitAnimations
-(void)animationOfUIKit
{
UIView *redView=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
redView.backgroundColor=[UIColor redColor];
[self.view addSubview:redView];
//開始動畫
[UIView beginAnimations:@"test" context:nil];
//動畫時長
[UIView setAnimationDuration:1];
/*
*要進行動畫設置的地方
*/
redView.backgroundColor=[UIColor blueColor];
redView.frame=CGRectMake(50, 50, 200, 200);
redView.alpha=0.5;
//動畫結束
[UIView commitAnimations];
}
2:第二種寫法也是比較常見的,UIKit已經對它進行了封裝,方便我門使用
-(void)animationOfBlock
{
//初始化一個View,用來顯示動畫
UIView *redView=[[UIView alloc]initWithFrame:CGRectMake(10, 80, 100, 100)];
redView.backgroundColor=[UIColor redColor];
[self.view addSubview:redView];
[UIView animateWithDuration:2.0 //時長
delay:0 //延遲時間
options:UIViewAnimationOptionTransitionFlipFromLeft//動畫效果
animations:^{
//動畫設置區域
redView.backgroundColor=[UIColor blueColor];
redView.frame=CGRectMake(50, 100, 200, 200);
redView.alpha=0.5;
} completion:^(BOOL finish){
//動畫結束時調用
NSLog(@"結束動畫");
}];
}
注意:關於動畫效果的枚舉如下:
常規動畫屬性設置(可以同時選擇多個進行設置)UIViewAnimationOptionLayoutSubviews:動畫過程中保證子視圖跟隨運動。
UIViewAnimationOptionAllowUserInteraction:動畫過程中允許用戶交互。
UIViewAnimationOptionBeginFromCurrentState:所有視圖從當前狀態開始運行。
UIViewAnimationOptionRepeat:重復運行動畫。
UIViewAnimationOptionAutoreverse :動畫運行到結束點後仍然以動畫方式回到初始點。
UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套動畫時間設置。
UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套動畫速度設置。
UIViewAnimationOptionAllowAnimatedContent:動畫過程中重繪視圖(注意僅僅適用於轉場動畫)。
UIViewAnimationOptionShowHideTransitionViews:視圖切換時直接隱藏舊視圖、顯示新視圖,而不是將舊視圖從父視圖移除(僅僅適用於轉場動畫)
UIViewAnimationOptionOverrideInheritedOptions :不繼承父動畫設置或動畫類型。
UIViewAnimationOptionCurveEaseInOut:動畫先緩慢,然後逐漸加速。
UIViewAnimationOptionCurveEaseIn :動畫逐漸變慢。
UIViewAnimationOptionCurveEaseOut:動畫逐漸加速。
UIViewAnimationOptionCurveLinear :動畫勻速執行,默認值。
UIViewAnimationOptionTransitionNone:沒有轉場動畫效果。
UIViewAnimationOptionTransitionFlipFromLeft :從左側翻轉效果。
UIViewAnimationOptionTransitionFlipFromRight:從右側翻轉效果。
UIViewAnimationOptionTransitionCurlUp:向後翻頁的動畫過渡效果。
UIViewAnimationOptionTransitionCurlDown :向前翻頁的動畫過渡效果。
UIViewAnimationOptionTransitionCrossDissolve:舊視圖溶解消失顯示下一個新視圖的效果。
UIViewAnimationOptionTransitionFlipFromTop :從上方翻轉效果。
UIViewAnimationOptionTransitionFlipFromBottom:從底部翻轉效果。
1:Core Animation是直接作用在CALayer上的(並非UIView上)非常強大的跨Mac OS X和iOS平台的動畫處理API,Core Animation的動畫執行過程都是在後台操作的,不會阻塞主線程。CAAnimation分為這4種,他們分別是:
CABasicAnimation---基本動畫 CAKeyframeAnimation---關鍵幀動畫 CAAnimationGroup---動畫組 CATransition---轉場動畫CABasicAnimation(基本動畫)
屬性說明:
keyPath :要改變的屬性名稱(傳字符串)
fromValue:keyPath相應屬性的初始值
toValue:keyPath相應屬性的結束值
動畫過程說明:
隨著動畫的進行,在長度為duration的持續時間內,keyPath相應屬性的值從fromValue漸漸地變為toValue
keyPath內容是CALayer的動畫Animatable屬性
animationWithKeyPath的值:
transform.rotation.x 圍繞x軸翻轉 參數:角度 angle2Radian(4)
transform.rotation.y 圍繞y軸翻轉 參數:同上
transform.rotation.z 圍繞z軸翻轉 參數:同上
transform.rotation 默認圍繞z軸
transform.scale.x x方向縮放 參數:縮放比例 1.5
transform.scale.y y方向縮放 參數:同上
transform.scale.z z方向縮放 參數:同上
transform.scale 所有方向縮放 參數:同上
transform.translation.x x方向移動 參數:x軸上的坐標 100
transform.translation.y x方向移動 參數:y軸上的坐標
transform.translation.z x方向移動 參數:z軸上的坐標
transform.translation 移動 參數:移動到的點 (100,100)
opacity 透明度 參數:透明度 0.5
backgroundColor 背景顏色 參數:顏色 (id)[[UIColor redColor] CGColor]
cornerRadius 圓角 參數:圓角半徑 5
borderWidth 邊框寬度 參數:邊框寬度 5
bounds 大小 參數:CGRect
contents 內容 參數:CGImage
contentsRect 可視內容 參數:CGRect 值是0~1之間的小數
hidden 是否隱藏
實例:
CALayer *myLayer = [CALayer layer];
myLayer.backgroundColor = [UIColor purpleColor].CGColor;
myLayer.frame = CGRectMake(50, 100, 120, 120);
myLayer.cornerRadius = 10;
[self.view.layer addSublayer:myLayer];
//移動
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:myLayer.position];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(myLayer.position.x+100, 100)];
//以X軸旋轉
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
rotationAnimation.fromValue = [NSNumber numberWithFloat:0.0];
rotationAnimation.toValue = [NSNumber numberWithFloat:6.0*M_PI];
//放大縮小
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
scaleAnimation.toValue = [NSNumber numberWithFloat:2];
//組合動畫
CAAnimationGroup *group = [CAAnimationGroup animation];
group.autoreverses = YES; //完成動畫後同樣反向也執行動畫
group.duration = 2.0; //動畫時間
group.animations = [NSArray arrayWithObjects:animation,rotationAnimation,scaleAnimation, nil];
group.repeatCount = 3;
/**
* PS:動畫結束以後,他會返回到自己原來的frame,如果想保持動畫結束時的狀態
* 添加下面屬性,並且此時要保證autoreverses屬性為NO,另外組合動畫的屬性設
* 置同樣也適用於單個動畫的設置
* group.removedOnCompletion = NO;
* group.fillMode = kCAFillModeForwards;
*/
//添加動畫
[myLayer addAnimation:group forKey:@"MyLayerAnimation"];
CAKeyframeAnimation關鍵幀動畫
CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值
屬性說明:
values:上述的NSArray對象。裡面的元素稱為“關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀
path:可以設置一個CGPathRef、CGMutablePathRef,讓圖層按照路徑軌跡移動。path只對CALayer的anchorPoint和position起作用。如果設置了path,那麼values將被忽略
keyTimes:可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀。如果沒有設置keyTimes,各個關鍵幀的時間是平分的,CABasicAnimation可看做是只有2個關鍵幀的CAKeyframeAnimation。Timing Function的作用:
Timing Function的會被用於變化起點和終點之間的插值計算.形象點說是Timing Function決定了動畫運行的節奏(Pacing),比如是均勻變化(相同時間變化量相同),先快後慢,先慢後快還是先慢再快再慢.
時間函數是使用的一段函數來描述的,橫座標是時間t取值范圍是0.0-1.0,縱座標是變化量x(t)也是取值范圍也是0.0-1.0 假設有一個動畫,duration是8秒,變化值的起點是a終點是b(假設是透明度),那麼在4秒處的值是多少呢? 可以通過計算為 a + x(4/8) * (b-a), 為什麼這麼計算呢?講實現的時間映射到單位值的時候4秒相對於總時間8秒就是0.5然後可以得到0.5的時候單位變化量是 x(0.5), x(0.5)/1 = 實際變化量/(b-a), 其中b-a為總變化量,所以實際變化量就是x(0.5) * (b-a) ,最後4秒時的值就是 a + x(0.5) * (b-a),所以計算的本質是映射.
五種預定義的時間函數名字的常量變量分別為
kCAMediaTimingFunctionLinear kCAMediaTimingFunctionEaseIn kCAMediaTimingFunctionEaseOut kCAMediaTimingFunctionEaseInEaseOut kCAMediaTimingFunctionDefault下圖展示了前面四種Timing Function的曲線圖,橫座標表示時間,縱座標表示變化量,這點需要搞清楚(並不是平面座標系中xy).
實例:分別使用屬性values及path兩種的效果;圍繞的點視圖塊進行轉動效果;
//values方式
-(void)animationValues
{
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(120, 350, 50, 50)];
myView.backgroundColor = [UIColor cyanColor];
[self.view addSubview:myView];
CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animation];
keyAnimation.keyPath = @"position";
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(200, 100)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
keyAnimation.values = @[value1,value2,value3,value4,value5];
keyAnimation.repeatCount = MAXFLOAT; //循環次數
keyAnimation.removedOnCompletion = NO;
keyAnimation.fillMode = kCAFillModeForwards;
keyAnimation.duration = 4.0;
keyAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
keyAnimation.delegate = self;
[myView.layer addAnimation:keyAnimation forKey:nil];
}
//path方式
-(void)animationPath
{
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(120, 350, 50, 50)];
myView.backgroundColor = [UIColor purpleColor];
[self.view addSubview:myView];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
CGMutablePathRef path=CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(50, 100, 220, 180));
animation.path=path;
CGPathRelease(path);
animation.repeatCount=MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 4.0f;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.delegate=self;
[myView.layer addAnimation:animation forKey:nil];
}
CAAnimationGroup(動畫組)
動畫組,是CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層後,組中所有動畫對象可以同時並發運行
屬性說明:
animations:用來保存一組動畫對象的NSArray
默認情況下,一組動畫對象是同時運行的,也可以通過設置動畫對象的beginTime屬性來更改動畫的開始時間
實例:創建一組動畫效果,多個動畫一起
-(void)animationGroup
{
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(120, 350, 50, 50)];
myView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:myView];
//貝塞爾曲線路徑
UIBezierPath *movePath = [UIBezierPath bezierPath];
[movePath moveToPoint:CGPointMake(50.0, 50.0)];
[movePath addQuadCurveToPoint:CGPointMake(130, 350) controlPoint:CGPointMake(300, 100)];
//關鍵幀動畫(位置)
CAKeyframeAnimation * posAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
posAnim.path = movePath.CGPath;
posAnim.removedOnCompletion = YES;
//縮放動畫
CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnim.removedOnCompletion = YES;
//透明動畫
CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"alpha"];
opacityAnim.fromValue = [NSNumber numberWithFloat:1.0];
opacityAnim.toValue = [NSNumber numberWithFloat:0.1];
opacityAnim.removedOnCompletion = YES;
//動畫組
CAAnimationGroup *animGroup = [CAAnimationGroup animation];
animGroup.animations = [NSArray arrayWithObjects:posAnim, scaleAnim, opacityAnim, nil];
animGroup.duration = 5;
animGroup.autoreverses = NO;
animGroup.removedOnCompletion = NO;
animGroup.fillMode = kCAFillModeRemoved;
[myView.layer addAnimation:animGroup forKey:nil];
}
CATransition(轉場動畫)
動畫屬性:
type:動畫過渡類型
subtype:動畫過渡方向
startProgress:動畫起點(在整體動畫的百分比)
endProgress:動畫終點(在整體動畫的百分比)
subtype:動畫過渡方向(默認為nil,如果指定了filter,那麼該屬性無效,kCATransitionFromRight,kCATransitionFromLeft,kCATransitionFromTop,kCATransitionFromBottom;分別表示:過渡從右邊、左邊、頂部、底部 開始)
轉場動畫的類型(NSString *type),還有很多私有API類型
fade : 交叉淡化過渡
push : 新視圖把舊視圖推出去
moveIn: 新視圖移到舊視圖上面
reveal: 將舊視圖移開,顯示下面的新視圖
cube : 立方體翻滾效果
oglFlip : 上下左右翻轉效果
suckEffect : 收縮效果,如一塊布被抽走
rippleEffect: 水滴效果
pageCurl : 向上翻頁效果
pageUnCurl : 向下翻頁效果
cameraIrisHollowOpen : 相機鏡頭打開效果
cameraIrisHollowClos : 相機鏡頭關閉效果
實例:兩個動畫效果,一個向上運動,一個向下運動的效果
//從下往上運動
-(void)animationTransition
{
//y點就是當要運動後到的Y值
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height-250, self.view.bounds.size.width, 250)];
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
CATransition *animation = [CATransition animation];
animation.duration = 1;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.fillMode = kCAFillModeForwards;
animation.type = kCATransitionMoveIn;
animation.subtype = kCATransitionFromLeft;
//添加動畫
[myView.layer addAnimation:animation forKey:nil];
}
//從上往下運動
-(void)animationPushTransition
{
//y點就是當要運動後到的Y值
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, 250)];
myView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:myView];
CATransition *animation = [CATransition animation];
animation.duration = 4.0;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.fillMode = kCAFillModeForwards;
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromBottom;
//添加動畫
[myView.layer addAnimation:animation forKey:nil];
}