ios開發中動畫那點事 – iPhone手機開發 iPhone軟體開發教學課程

一:UIKit動畫

在介紹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:從底部翻轉效果。


二:CoreAnimation介紹

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];

}

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *