iOS動畫-從UIView到Core Animation

首先,介紹一下UIView相關的動畫。ios

  1. UIView普通動畫:
[UIView beginAnimations: context:];
 [UIView commitAnimations];

動畫屬性設置:spring

 1     //動畫持續時間
 2     [UIView setAnimationDuration:(NSTimeInterval)];
 3     //動畫的代理對象
 4     [UIView setAnimationDelegate:(nullable id)];
 5     //設置動畫將開始時代理對象執行的SEL
 6     [UIView setAnimationWillStartSelector:(nullable SEL)];
 7     //設置動畫延遲執行的時間
 8     [UIView setAnimationDelay:(NSTimeInterval)];
 9     //設置動畫的重複次數
10     [UIView setAnimationRepeatCount:(float)];
11     //設置動畫的曲線
12     /*
13      UIViewAnimationCurve的枚舉值:
14      UIViewAnimationCurveEaseInOut,         // 慢進慢出(默認值)
15      UIViewAnimationCurveEaseIn,            // 慢進
16      UIViewAnimationCurveEaseOut,           // 慢出
17      UIViewAnimationCurveLinear             // 勻速
18      */
19     [UIView setAnimationCurve:(UIViewAnimationCurve)];
20     //設置是否從當前狀態開始播放動畫
21     /*假設上一個動畫正在播放,且還沒有播放完畢,咱們將要進行一個新的動畫:
22      當爲YES時:動畫將從上一個動畫所在的狀態開始播放
23      當爲NO時:動畫將從上一個動畫所指定的最終狀態開始播放(此時上一個動畫立刻結束)*/
24     [UIView setAnimationBeginsFromCurrentState:YES];
25     //設置動畫是否繼續執行相反的動畫
26     [UIView setAnimationRepeatAutoreverses:(BOOL)];
27     //是否禁用動畫效果(對象屬性依然會被改變,只是沒有動畫效果)
28     [UIView setAnimationsEnabled:(BOOL)];
29     //設置視圖的過渡效果
30     /* 第一個參數:UIViewAnimationTransition的枚舉值以下
31      UIViewAnimationTransitionNone,              //不使用動畫
32      UIViewAnimationTransitionFlipFromLeft,      //從左向右旋轉翻頁
33      UIViewAnimationTransitionFlipFromRight,     //從右向左旋轉翻頁
34      UIViewAnimationTransitionCurlUp,            //從下往上捲曲翻頁
35      UIViewAnimationTransitionCurlDown,          //從上往下捲曲翻頁
36      第二個參數:須要過渡效果的View
37      第三個參數:是否使用視圖緩存,YES:視圖在開始和結束時渲染一次;NO:視圖在每一幀都渲染*/
38     [UIView setAnimationTransition:(UIViewAnimationTransition) forView:(nonnull UIView *) cache:(BOOL)];

舉2個例子:數組

 1     [UIView beginAnimations:@"xxx" context:nil];
 2     [UIView setAnimationDuration:5];
 3     [UIView setAnimationRepeatCount:MAXFLOAT];
 4     [UIView setAnimationDelegate:self];
 5     [UIView setAnimationDelay:3];
 6     [UIView setAnimationWillStartSelector:@selector(animationWillStart)];
 7     [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
 8     [UIView setAnimationRepeatAutoreverses:YES];
 9     
10     self.iView.frame = CGRectMake(200, 400, 100, 100);
11     
12     [UIView commitAnimations];
 1     [UIView beginAnimations:@"xxx" context:nil];
 2     [UIView setAnimationDuration:2];
 3     [UIView setAnimationRepeatCount:MAXFLOAT];
 4     [UIView setAnimationDelegate:self];
 5     //[UIView setAnimationDelay:3];
 6     [UIView setAnimationWillStartSelector:@selector(animationWillStart)];
 7     [UIView setAnimationCurve:UIViewAnimationCurveLinear];
 8     //[UIView setAnimationRepeatAutoreverses:YES];
 9     
10     [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.iView cache:YES];
11     
12     [UIView commitAnimations];

 

      2.   UIView Block動畫緩存

1 [UIView animateWithDuration:(NSTimeInterval)//動畫時間
2     animations:^{
3         //執行的動畫
4     }];
1 [UIView animateWithDuration:(NSTimeInterval)//動畫時間
2                      animations:^{
3         //執行的動畫
4     } completion:^(BOOL finished) {
5         //動畫結束的回調
6     }];
1 [UIView animateWithDuration:(NSTimeInterval)//動畫時間
2                           delay:(NSTimeInterval)//動畫延遲時間
3                         options:(UIViewAnimationOptions)//動畫過渡效果
4                      animations:^{
5         //執行動畫
6     } completion:^(BOOL finished) {
7         //動畫結束回調
8     }]
UIViewAnimationOptions的枚舉值:
    UIViewAnimationOptionLayoutSubviews            //進行動畫時佈局子控件
    UIViewAnimationOptionAllowUserInteraction      //進行動畫時容許用戶交互
    UIViewAnimationOptionBeginFromCurrentState     //從當前狀態開始動畫
    UIViewAnimationOptionRepeat                    //無限重複執行動畫
    UIViewAnimationOptionAutoreverse               //執行動畫迴路
    UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫的執行時間設置
    UIViewAnimationOptionOverrideInheritedCurve    //忽略嵌套動畫的曲線設置
    UIViewAnimationOptionAllowAnimatedContent      //轉場:進行動畫時重繪視圖
    UIViewAnimationOptionShowHideTransitionViews   //轉場:移除(添加和移除圖層的)動畫效果
    UIViewAnimationOptionOverrideInheritedOptions  //不繼承父動畫設置
    
    UIViewAnimationOptionCurveEaseInOut            //時間曲線,慢進慢出(默認值)
    UIViewAnimationOptionCurveEaseIn               //時間曲線,慢進
    UIViewAnimationOptionCurveEaseOut              //時間曲線,慢出
    UIViewAnimationOptionCurveLinear               //時間曲線,勻速
    
    UIViewAnimationOptionTransitionNone            //轉場,不使用動畫
    UIViewAnimationOptionTransitionFlipFromLeft    //轉場,從左向右旋轉翻頁
    UIViewAnimationOptionTransitionFlipFromRight   //轉場,從右向左旋轉翻頁
    UIViewAnimationOptionTransitionCurlUp          //轉場,下往上捲曲翻頁
    UIViewAnimationOptionTransitionCurlDown        //轉場,從上往下捲曲翻頁
    UIViewAnimationOptionTransitionCrossDissolve   //轉場,交叉消失和出現
    UIViewAnimationOptionTransitionFlipFromTop     //轉場,從上向下旋轉翻頁
    UIViewAnimationOptionTransitionFlipFromBottom  //轉場,從下向上旋轉翻頁

這3個動畫比較簡單,再也不多作敘述。併發

 

 

Spring動畫
ios7.0之後新增了Spring動畫(IOS系統動畫大部分採用Spring Animation, 適用全部可被添加動畫效果的屬性)ide

[UIView animateWithDuration:(NSTimeInterval)//動畫持續時間
                   delay:(NSTimeInterval)//動畫延遲執行的時間
  usingSpringWithDamping:(CGFloat)//震動效果,範圍0~1,數值越小震動效果越明顯
   initialSpringVelocity:(CGFloat)//初始速度,數值越大初始速度越快
                 options:(UIViewAnimationOptions)//動畫的過渡效果
              animations:^{
                 //執行的動畫
 }
                  completion:^(BOOL finished) {
                 //動畫執行提交後的操做
 }];
[UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.2 initialSpringVelocity:5 options:UIViewAnimationOptionRepeat animations:^{
        self.iView.frame = CGRectMake(200, 400, 100, 100);
        self.iView.transform = CGAffineTransformRotate(self.iView.transform, M_PI);
    } completion:^(BOOL finished) {
        
    }];

 

Keyframes動畫:函數

IOS7.0後新增了關鍵幀動畫,支持屬性關鍵幀,不支持路徑關鍵幀
 [UIView animateKeyframesWithDuration:(NSTimeInterval)//動畫持續時間
                            delay:(NSTimeInterval)//動畫延遲執行的時間
                          options:(UIViewKeyframeAnimationOptions)//動畫的過渡效果
                       animations:^{
                     //執行的關鍵幀動畫
 }
                       completion:^(BOOL finished) {
                     //動畫執行提交後的操做
 }];

 

Core Animation

CABasicAnimation:

//  經常使用屬性:
    
     duration:動畫的持續時間
     repeatCount:重複次數,無限循環能夠設置HUGE_VALF或者MAXFLOAT
     repeatDuration:重複時間
     speed:動畫速率,決定動畫時間的倍率。當speed爲2時,動畫時間爲設置的duration的1/2。
     timeOffset:動畫時間偏移量。好比設置動畫時長爲3秒,當設置timeOffset爲1.5時,當前動畫會從中間位置開始,並在到達指定位置時,走完以前跳過的前半段動畫。
     removedOnCompletion:默認爲YES,表明動畫執行完畢後就從圖層上移除,圖形會恢復到動畫執行前的狀態。若是想讓圖層保持顯示動畫執行後的狀態,那就設置爲NO,不過還要設置fillMode爲kCAFillModeForwards
     fillMode:決定當前對象在非active時間段的行爲。好比動畫開始以前或者動畫結束以後
          kCAFillModeRemoved:這個是默認值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到以前的狀態
          kCAFillModeForwards:當動畫結束後,layer會一直保持着動畫最後的狀態
          kCAFillModeBackwards:在動畫開始前,只須要將動畫加入了一個layer,layer便當即進入動畫的初始狀態並等待動畫開始。
          kCAFillModeBoth:這個其實就是上面兩個的合成.動畫加入後開始以前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態
     
     beginTime:能夠用來設置動畫延遲執行時間,若想延遲2s,就設置爲CACurrentMediaTime()+2,CACurrentMediaTime()爲圖層的當前時間
     timingFunction:速度控制函數,控制動畫運行的節奏
     
          kCAMediaTimingFunctionLinear(線性):勻速,給你一個相對靜態的感受
          kCAMediaTimingFunctionEaseIn(漸進):動畫緩慢進入,而後加速離開
          kCAMediaTimingFunctionEaseOut(漸出):動畫全速進入,而後減速的到達目的地
          kCAMediaTimingFunctionEaseInEaseOut(漸進漸出):動畫緩慢的進入,中間加速,而後減速的到達目的地。這個是默認的動畫行爲。
     
     delegate:動畫代理
     autoreverses:動畫完成後是否以動畫形式回到初始值
     fromValue:keyPath相應屬性的初始值
     toValue:keyPath相應屬性的結束值
     byValue:keyPath相應屬性的改變值
     
     `fromValue`,`toValue`和`byValue`屬性能夠用不少種方式來組合,但爲了防止衝突,不能一次性同時指定這三個值。例如,若是指定了`fromValue`等於2,`toValue`等於4,`byValue`等於3,那麼Core Animation就不知道結果究竟是4(`toValue`)仍是5(`fromValue + byValue`)了。他們的用法在`CABasicAnimation`頭文件中已經描述的很清楚了,因此在這裏就不重複了。總的說來,就是隻須要指定`toValue`或者`byValue`,剩下的值均可以經過上下文自動計算出來。
 

實例化方法:佈局

CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];動畫

其中keyPath表示動畫類型,經常使用的keyPath:url

 

舉一個例子:

CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
basicAnimation.duration = 5;
basicAnimation.removedOnCompletion = NO;
basicAnimation.fillMode = kCAFillModeForwards;
 // basicAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
basicAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
    
[self.iView.layer addAnimation:basicAnimation forKey:@"rotation"];

「position」也能夠替換成上圖其餘的值,"fromvalue"/"toValue"/"byValue"要與動畫類型'keypath'對應。

 

CAKeyframeAnimation:關鍵幀動畫

關鍵幀動畫和CABasicAnimation同樣是CApropertyAnimation的子類,可是CABasicAnimation只能從一個數值(fromValue)變到另外一個數值(toValue)或者添加一個增量數值(byValue),而CAKeyframeAnimation使用values數組能夠設置多個關鍵幀,同時能夠利用path能夠進行位置或者錨點的動畫操做。

經常使用屬性:

values:關鍵幀數組對象,裏面每個元素即爲一個關鍵幀,動畫會在對應的時間段內,依次執行數組中每個關鍵幀的動畫。
path:動畫路徑對象,能夠指定一個路徑,在執行動畫時路徑會沿着路徑移動,Path在動畫中只會影響視圖的Position。
keyTimes:設置關鍵幀對應的時間點,範圍:0-1。若是沒有設置該屬性,則每一幀的時間平分。
timingFunctions:每一幀對應的動畫節奏。
rotationMode:動畫沿路徑旋轉方式。例如讓一個視圖按照一條三次貝塞爾曲線移動,若是rotationMode=kCAAnimationRotateAuto,那麼這個視圖會沿着曲線的切線移動,而不是直來直去的。以下圖所示:

 

 

舉例:

if (tag == 6) {
        //使用「values」
        keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
        keyFrameAni.duration = 0.3;
        keyFrameAni.values = @[@(-(4) / 180.0*M_PI),@((4) / 180.0*M_PI),@(-(4) / 180.0*M_PI)];
        keyFrameAni.repeatCount=MAXFLOAT;
    }else if (tag == 7){
        //使用「path」路徑
        keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:_aniLayer.position];
        [path addCurveToPoint:CGPointMake(300, 500) controlPoint1:CGPointMake(100, 400) controlPoint2:CGPointMake(300, 450)];
        keyFrameAni.path = path.CGPath;
        keyFrameAni.duration = 1;
1
    }
    [_aniLayer addAnimation:keyFrameAni forKey:@"keyFrameAnimation"];

 

CASpringAnimation

CASpringAnimation是iOS9才引入的動畫類,效果相似於UIView的spring動畫,不過比其增長了質量,勁度係數等屬性的擴展,繼承於CABaseAnimation,用法也很簡單:

CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"position"];
    //質量,影響圖層運動時的彈簧慣性,質量越大,彈簧拉伸和壓縮的幅度越大
    springAnimation.mass = 1;
    //剛度係數(勁度係數/彈性係數),剛度係數越大,形變產生的力就越大,運動越快
    springAnimation.stiffness = 10;
    //阻尼係數,阻止彈簧伸縮的係數,阻尼係數越大,中止越快
    springAnimation.damping = 3;
    //初始速率,動畫視圖的初始速度大小 Defaults to zero
    //速率爲正數時,速度方向與運動方向一致,速率爲負數時,速度方向與運動方向相反
    springAnimation.initialVelocity = 10;
    //settlingDuration:估算時間 返回彈簧動畫到中止時的估算時間,根據當前的動畫參數估算
    springAnimation.duration = springAnimation.settlingDuration;
    springAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(100, 400, 100, 100)];
    [self.iView.layer addAnimation:springAnimation forKey:@"spring"];

 

CATransition:轉場動畫

CATransition是CAAnimation的子類,用於作轉場動畫,可以爲層提供移出屏幕和移入屏幕的動畫效果。iOS比Mac OS X的轉場動畫效果少一點
UINavigationController就是經過CATransition實現了將控制器的視圖推入屏幕的動畫效果
動畫屬性:(有的屬性是具有方向的,詳情看下圖)
type:動畫過渡類型
subtype:動畫過渡方向
startProgress:動畫起點(在總體動畫的百分比)
endProgress:動畫終點(在總體動畫的百分比)
 
-(void)transitionAnimation{
    self.index++;
    if (self.index>7) {
        self.index=1;
    }
    self.iImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpg",[NSNumber numberWithInteger:self.index]]];
    CATransition *transition = [CATransition animation];
    transition.type = @"cube";
    //transition.subtype = @"fromRight";
    transition.duration = 2;
    [self.iImageView.layer addAnimation:transition forKey:nil];
}

這裏是以"cube"和"pageCurl"的效果圖,就是上面的代碼,沒有作成gif圖,能夠想象一下哈!

 

CAAnimationGroup:動畫組

動畫組,是CAAnimation的子類,能夠保存一組動畫對象,將CAAnimationGroup對象加入層後,組中全部動畫對象能夠同時併發運行

屬性說明:
animations:用來保存一組動畫對象的NSArray
默認狀況下,一組動畫對象是同時運行的,也能夠經過設置動畫對象的beginTime屬性來更改動畫的開始時間

示例:

CAAnimationGroup *group = [CAAnimationGroup animation];
    
    //    建立旋轉動畫對象
    CABasicAnimation *retate = [CABasicAnimation animation];
    //    layer的旋轉屬性
    retate.keyPath = @"transform.rotation";
    //    角度
    retate.toValue = @(M_PI);
    
    //    建立縮放動畫對象
    CABasicAnimation *scale = [CABasicAnimation animation];
    //    縮放屬性
    scale.keyPath = @"transform.scale";
    //    縮放比例
    scale.toValue = @(0.0);
    //    添加到動畫組當中
    group.animations = @[retate,scale];
    //           執行動畫時間
    group.duration = 2.0;
    //    執行完之後不要刪除動畫
    group.removedOnCompletion = NO;
    //          保持最新的狀態
    group.fillMode = kCAFillModeForwards;
    
    [self.view.layer addAnimation:group forKey:nil];

 

 

文章轉載:https://www.jianshu.com/p/9fa025c42261

相關文章
相關標籤/搜索