原文連接: http://www.cnblogs.com/zzuliliu/p/5468732.htmlhtml
本篇文章主要講解iOS中動畫的使用。spring
一、Core Animation,核心動畫。緩存
核心動畫執行過程都是在後臺操做的,不會阻塞主線程。Core Animation是直接做用在CALayer上的,並不是UIView。post
CAAnimation 是全部 Core Animation 動畫類的父類,CAAnimation是一個抽象類,不能直接使用,應該使用它的子類。CAAnimation經常使用的子類有如下三個:動畫
CAPropertyAnimation,屬性動畫url
CATransition,轉場動畫spa
CAAnimationGroup,組動畫線程
其中,CAPropertyAnimation也是一個抽象類,咱們通常使用它的兩個子類:code
CABasicAnimation,基礎動畫,orm
CAKeyframeAnimation,幀動畫
另外有一個協議:CAMediaTiming。
1.一、CABasicAnimation,基礎動畫。經過上面的介紹,咱們能夠知道,核心動畫是做用在CALayer層,所以,基礎動畫是經過改變對象的layer的某個屬性來實現動畫效果的。至於CALayer的屬性有哪些,你們能夠自行看API,我這裏僅就 position 屬性來演示動畫效果。下面看代碼:
1 - (IBAction)CABasicAnimation:(UIButton *)sender { 2 //參數須要是layer的屬性,或者是屬性的屬性的名字 3 CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"position.x"]; 4 basic.fromValue = @100; 5 basic.toValue = @250; 6 basic.duration = 3; 7 basic.repeatCount = 1; 8 //須要手動改變位置,(若是須要改變position的真實位置) 9 // self.redView.layer.position = CGPointMake(250, 100); 10 //key,標識 11 [self.redView.layer addAnimation:basic forKey:nil]; 12 }
解釋一下上面的代碼,Line3中建立了一個動畫,這個動畫是改變 某個對象在x軸的位置,即 position.x 來實現的;Line4中制定了x的起始位置,Line5中指定了x的終止位置,Line6設置動畫執行時間爲3S,Line7設置動畫重複次數爲1,Line11中,將這個動畫指定給 self.redView.layer 。
當上面的動畫執行完成後,咱們會發現,self.redView又回到了初始位置,也就是說,動畫並不會真正改變layer的屬性值。咱們能夠經過Line9中的代碼,來實際改變layer的屬性值,讓對象停留在終止位置。
1.二、CAKeyframeAnimation,關鍵幀動畫。這個和基礎動畫很相似,只不過是能夠經過添加一組基礎動畫來執行,下面直接上代碼,代碼解釋參考上面的:
1 //關鍵幀動畫 2 - (IBAction)keyFrameAnimation:(UIButton *)sender { 3 4 CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 5 CGPoint point0 = CGPointMake(100, 100); 6 CGPoint point1 = CGPointMake(100, 200); 7 CGPoint point2 = CGPointMake(200, 200); 8 CGPoint point3 = CGPointMake(200, 300); 9 CGPoint point4 = CGPointMake(150, 300); 10 CGPoint point5 = CGPointMake(175, 250); 11 CGPoint point6 = CGPointMake(175, 100); 12 13 NSValue *value1 = [NSValue valueWithCGPoint:point0]; 14 NSValue *value2 = [NSValue valueWithCGPoint:point1]; 15 NSValue *value3 = [NSValue valueWithCGPoint:point2]; 16 NSValue *value4 = [NSValue valueWithCGPoint:point3]; 17 NSValue *value5 = [NSValue valueWithCGPoint:point4]; 18 NSValue *value6 = [NSValue valueWithCGPoint:point5]; 19 NSValue *value7 = [NSValue valueWithCGPoint:point6]; 20 21 //根據一組點來建立動畫 22 keyFrameAnimation.values = @[value1, value2, value3, value4, value5, value6, value7, value1]; 23 keyFrameAnimation.duration = 10; 24 [self.redView.layer addAnimation:keyFrameAnimation forKey:nil]; 25 }
上面的代碼,你們能夠自行建立一個View,即代碼中的 self.redView,演示一下就明白了。
1.3 CATransition轉場動畫。下面看代碼:
- (IBAction)transitionAnimation:(UIButton *)sender { CATransition *transition = [CATransition animation]; transition.type = @"rippleEffect"; //動畫過渡類型 transition.subtype = kCATransitionFromLeft; //動畫過分方向 transition.repeatCount = HUGE_VALL; //動畫重複次數,最大次數 transition.duration = 2; //動畫持續時間 [self.redView.layer addAnimation:transition forKey:nil]; }
下面我羅列了一些過渡類型,供你們參考使用:
1 pageCurl 向上翻一頁 2 pageUnCurl 向下翻一頁 3 rippleEffect 滴水效果 4 suckEffect 收縮效果,如一塊布被抽走 5 cube 立方體效果 6 oglFlip 上下翻轉效果
1.4 CAAnimationGroup。組動畫實際上就是能夠將上面的幾種動畫類型隨意組合添加到一個對象上。下面看代碼:
1 - (IBAction)groupAnimation:(UIButton *)sender { 2 //建立一個縮放動畫 3 CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 4 basic.fromValue = @1; 5 basic.toValue = @0.75; 6 //建立一個關鍵幀動畫,從一個位置到另外一個位置 7 CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 8 CGPoint point1 = CGPointMake(100, 100); 9 CGPoint point2 = CGPointMake(300, 300); 10 NSValue *value1 = [NSValue valueWithCGPoint:point1]; 11 NSValue *value2 = [NSValue valueWithCGPoint:point2]; 12 keyFrameAnimation.values = @[value1, value2]; 13 //建立一個動畫組 14 CAAnimationGroup *group = [CAAnimationGroup animation]; 15 group.duration = 4; 16 group.repeatCount = 3; 17 //將上面的兩種動畫添加到動畫組中,動畫將同步執行 18 [group setAnimations:@[basic,keyFrameAnimation]]; 19 //下面的代碼會最終改變對象的位置,不然對象在動畫完成後會回到初始位置 20 self.redView.layer.position = CGPointMake(300, 300); 21 //添加動畫組 22 [self.redView.layer addAnimation:group forKey:nil]; 23 }
1.5 CASpringAnimation,彈簧動畫,繼承於CABasicAnimation。都不難,上代碼吧:
- (IBAction)springAnimation:(UIButton *)sender { CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"transform.rotation"]; //質量越大,慣性越大 spring.mass = 1; //阻尼係數,越大中止的越快 spring.damping = 0.2; spring.fromValue = @0.2;//transform.rotation的初始值 spring.toValue = @0.75;//transform.rotation的結束值 spring.repeatCount = 1; spring.autoreverses = YES;//自動回彈 //初始速度 spring.initialVelocity = 5; spring.duration = spring.settlingDuration; [self.redView.layer addAnimation:spring forKey:@"spring"]; }
下面我總結了一下keypath值,你們能夠參考:
transform.scale = 比例轉換 transform.scale.x = 闊的比例轉換 transform.scale.y = 高的比例轉換 transform.rotation.z = 平面圖的旋轉 opacity = 透明度 margin zPosition backgroundColor 背景顏色 cornerRadius 圓角 borderWidth bounds contents contentsRect cornerRadius frame hidden mask masksToBounds opacity position shadowColor shadowOffset shadowOpacity shadowRadius
上面就是核心動畫的所有內容了,基本就是以代碼來說解,這些東西原理上沒什麼可說的,主要是知道怎麼用。下面說說UIView動畫。
二、UIView動畫。UIKit直接將動畫集成到UIView類中,當內部的一些屬性發生變化時,UIView將爲這些改變提供動畫支持。執行動畫的工做由UIView類自動完成,但仍但願在執行動畫時通知視圖,所以須要將改變屬性的代碼放在 [UIView beginAnimations:nil context:nil] 和 [UIView commitAnimations] 之間。
通常來講,可以影響控件外形的屬性均可以使用動畫,而UIView動畫的實現由兩種方式,咱們先看第一種方式,下面看代碼,一個改變控件Frame的動畫:
1 - (IBAction)changeFrame:(UIButton *)sender { 2 //第一個參數,動畫標示 3 [UIView beginAnimations:@"changeFrame" context:nil]; 4 //設置動畫次數 5 [UIView setAnimationRepeatCount:100]; 6 //設置動畫時長 7 [UIView setAnimationDuration:1]; 8 //設置動畫速率 9 [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 10 CGRect frame = self.showView.frame; 11 frame.origin.y = 200; 12 //改變frame,y值 13 self.showView.frame = frame; 14 //開始動畫 15 [UIView commitAnimations]; 16 }
你們看註釋應該能明白這段代碼的意思。
再上一段代碼,縮放動畫:
1 //縮放動畫 2 - (IBAction)scaleButtonAction:(UIButton *)sender { 3 4 [UIView beginAnimations:@"UIView" context:nil]; 5 self.showView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.5, 1.5); 6 }
旋轉動畫:
1 // 旋轉 2 - (IBAction)rotateButtonAction:(UIButton *)sender { 3 [UIView beginAnimations:nil context:nil]; 4 // 第一個參數: 以誰爲基準進行旋轉 5 // 第二個參數: 旋轉的弧度 6 // CGAffineTransformIdentity 原始形變 7 [UIView setAnimationDuration:1]; 8 self.showView.transform = CGAffineTransformRotate(self.showView.transform, -M_PI / 180 * 30); 9 [UIView commitAnimations]; 10 }
咱們再來看一下另外一種方式實現的UIView動畫。
簡單的Block動畫:
1 // 簡單block動畫 2 - (IBAction)simpleBlock:(UIButton *)sender{ 3 [UIView animateWithDuration:2 animations:^{ 4 CGPoint point = self.planeImageView.center; 5 point.y += 100; 6 self.planeImageView.center = point; 7 } completion:^(BOOL finished) { 8 NSLog(@"動畫結束"); 9 [UIView animateWithDuration:2 animations:^{ 10 CGPoint point = self.planeImageView.center; 11 point.y -= 100; 12 self.planeImageView.center = point; 13 } completion:nil]; 14 15 }]; 16 }
複雜的Block動畫:
1 // 複雜的block 2 - (IBAction)complexBlock:(UIButton *)sender { 3 [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 4 self.planeImageView.transform = CGAffineTransformRotate(self.planeImageView.transform, M_PI / 180 * 90); 5 } completion:^(BOOL finished) { 6 // 還原到初始形變 7 // self.planeImageView.transform = CGAffineTransformIdentity; 8 }]; 9 }
轉場動畫:
1 // 過分動畫, 轉場動畫 2 - (IBAction)transitionAnimation:(UIButton *)sender { 3 [UIView beginAnimations:nil context:nil]; 4 [UIView setAnimationDuration:2]; 5 // 第一個參數: 轉場動畫的類型 6 // 第二個參數: 給哪一個對象添加轉場動畫 7 // 第三個參數: 緩存設置(YES執行效率更高) 8 [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.label cache:YES]; 9 self.label.text = @"熊大熊二的故事"; 10 [UIView commitAnimations]; 11 }
彈簧動畫:
1 // 彈簧動畫 2 - (IBAction)sprintAnimation:(UIButton *)sender { 3 // 1. 動畫時長 4 // 2. 延遲時間 5 // 3. 阻尼係數, 越大, 彈簧形變越小 6 // 4. 速度 7 // 5. 動畫類型選項 8 [UIView animateWithDuration:2 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:10 options:UIViewAnimationOptionCurveLinear animations:^{ 9 CGPoint point = self.planeImageView.center; 10 point.y += 260; 11 self.planeImageView.center = point; 12 13 } completion:^(BOOL finished) { 14 NSLog(@"動畫結束"); 15 }]; 16 }
你們能夠發現,第二種實現方式其實是對第一種方式使用了Block封裝,相對來講,第二種實現方式更加的方便。而仔細看核心動畫和UIView動畫,咱們也能夠發現,實際上,UIView動畫就是對核心動畫的封裝,使用起來更加的方便。