你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS編程技術 >> iOS核心動畫以及UIView動畫的介紹

iOS核心動畫以及UIView動畫的介紹

編輯:IOS編程技術

我們看到很多App帶有絢麗狂拽的特效,別出心裁的控件設計,很大程度上提高了用戶體驗,在增加了實用性的同時,也賦予了app無限的生命力。這些華麗的效果很多都是基於iOS的核心動畫原理實現的,本文介紹一些iOS開發中最基本的動畫效果實現,掌握了基本屬性,才可以繪制出更華麗的效果。

 

一、概念擴充

 1、核心動畫:

  Core Animation,它是一組非常強大的動畫處理API,使用它能做出非常炫麗的動畫效果,而且往往是事半功倍。 Core Animation可以用在Mac OS X和iOS平台。在iOS平台中,動畫效果會略少一些。另外,iOS開發中實現動畫的方式也不只是核心動畫一種,後面會介紹UIView的幾種動畫。

 2、執行和創建動畫過程:

 (1)Core Animation的動畫執行過程都是在後台操作的,不會阻塞主線程。要注意的是,Core Animation是直接作用在CALayer上的,並非UIView。所以,CALayer是核心動畫的基礎。

 (2)關於框架:iOS7以後,不再需要導入QuartzCore.framework框架和主頭文件<QuartzCore/QuartzCore.h>

 (3)基本的創建動畫流程

  •   創建動畫對象;
  •   設置動畫屬性;
  •   把動畫對象添加到某個 CALayer 對象上;
  •   需要停止動畫:可以調用 remove 方法移除動畫。

3、動畫類型:後面做詳細的使用介紹

  •   屬性動畫:設定某個屬性的值,可以實現屬性動畫。
  •   基本動畫(CABasicAnimation):設定某個屬性從某個值到某個值,實現基本動畫。
  •   關鍵幀動畫(CAKeyframeAnimation):設定某個屬性的值從某個值到某個值,再到某個值。按照關鍵值改變的順序,實現動畫。  
  •   組動畫(CAAnimationGroup):把所有其他的動畫添加到組裡面,這樣就可以按照添加的動畫一次執行。
  •   轉場動畫(CATransition):從一個場景轉換到另一個場景,系統已經實現好了,不需要我們再去寫,按照需求直接調用。

 

4、本質與繼承關系

(1)本質:在後台移動圖層中的內容,  執行完畢後圖層本身的位置並沒有發生變化。

(2)所有的動畫都繼承自CAAnimation

 

 

二、CAAnimation

 

1、定義:

   所有動畫對象的父類,負責控制動畫的持續時間和速度,是個抽象類,不能直接使用,應該使用它具體的子類。

2、 屬性解析:(很多屬性都是來自CAMediaTiming協議)

  • duration:        動畫的持續時間,默認0.25s
  • repeatCount:      動畫的重復次數
  • repeatDuration: 動畫的重復時間
  • removedOnCompletion:默認為YES,代表動畫執行完畢後就從圖層上移除,圖形會恢復到動畫執行前的狀態。如果想讓圖層保持顯示動畫執行後的狀態,那就設置為NO,不過還要設置fillMode為kCAFillModeForwards
  • fillMode:決定當前對象在非active時間段的行為.比如動畫開始之前,動畫結束之後
  • beginTime:可以用來設置動畫延遲執行時間,若想延遲2s,就設置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當前時間
  • timingFunction:速度控制函數,控制動畫運行的節奏

 3、隱式代理:delegate

 (1)  CAAnimation有一個id類型的delegate屬性,但是此屬性沒有遵守任何協議,本身也沒有任何代理協議。

 (2)  實現代理方法:注意,這裡的兩個方法,是在NSObject擴展中聲明的,所以是本身就是NSObject的方法,每一個類都能實現該方法。o(╯□╰)o。。

  • 監聽動畫開始   -(void)animationDidStart:(CAAnimation *)anim  
  • 監聽動畫結束   - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;  

 (3)給CAAnimation的delegate賦值(說明誰來代理)、重寫代理方法,就可以實現“隱式”代理。

 

三、CAPropertyAnimation

 

1、定義:

是CAAnimation的子類,也是個抽象類,要想創建動畫對象,應該使用它的兩個子類:CABasicAnimation和CAKeyframeAnimation。

2、屬性解析:

  • keyPath:將CALayer的一個屬性名稱作為keyPath(NSString類型),並且對CALayer的這個屬性的值進行修改,達到相應的動畫效果。比如,指定@”position”為keyPath,就修改CALayer的position屬性的值,以達到平移的動畫效果。下面三張圖是官方給出的keyPath:

(1)圖1:position屬性———CGPoint類型

 

(2)圖2:frame和bounds屬性 ———CGRect類型

 

 

(3)圖3:transform屬性 ————CATransform3D 類型

 

 

四、CABasicAnimation 基本動畫

 

1、定義:

   基本動畫,CAPropertyAnimation的子類。通過設置keyPath,兩個值之間的變化實現動畫。

2、屬性解析: 

  • fromValue:  keyPath相應屬性的初始值
  • toValue:      keyPath相應屬性的結束值

  隨著動畫的進行,在長度為duration的持續時間內,keyPath相應屬性的值從fromValue漸漸地變為toValue,如果fillMode=kCAFillModeForwardsremovedOnComletion=NO,那麼在動畫執行完畢後,圖層會保持顯示動畫執行後的狀態。但在實質上,圖層的屬性值還是動畫執行前的初始值,並沒有真正被改變。比如,CALayer的position初始值為(0,0),CABasicAnimation的fromValue為(10,10),toValue為(100,100),雖然動畫執行完畢後圖層保持在(100,100)這個位置,實質上圖層的position還是為(0,0)

 

3、代碼案例:

  給出一個基本動畫和關鍵幀動畫的基本配置案例

  效果:

     

 

#pragma mark - 基本動畫:按路徑移動(默認返回原位)
- (IBAction)moveAtPathBack:(UIButton *)sender {
    
    //設置keyPath 為:transform.translation.x
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
    
    //起始值
    animation.fromValue= @(150);
    //到達值
    animation.toValue = @(-150);
    animation.duration=1;
    
    //要添加到layer
    [self.button.layer addAnimation:animation forKey:nil];
    
    
}

#pragma mark - 基本動畫:按路徑移動(不返回原位)

- (IBAction)moveAtPath:(id)sender {
    
    //設置keyPath 為:transform.translation.x
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
    
    animation.fromValue= @(150);
    animation.toValue = @(-150);
    animation.duration=1;
    
    //不回到原位置,但是控件的“真身”還在原位
    animation.removedOnCompletion=NO;
    
    //保持的狀態
    animation.fillMode=kCAFillModeForwards;
    
    [self.button.layer addAnimation:animation forKey:nil];
}


#pragma mark - 基本動畫:旋轉

- (IBAction)rotate:(UIButton *)sender {
    
    //設置keyPath 為:transform.rotation.y
    
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    
    //轉一周
    NSNumber * num = @(M_PI*2);
    
    animation.toValue=num;
    animation.removedOnCompletion=NO;
    animation.fillMode=kCAFillModeForwards;
    //轉了3秒
    animation.duration=3;
    //重復次數無限大
    animation.repeatCount=CGFLOAT_MAX;
    [self.button.layer addAnimation:animation forKey:nil];
    
}

 

五、CAKeyframeAnimation 關鍵幀動畫

 

1、定義:

   關鍵幀動畫,也是CApropertyAnimation的子類。通過設置keyPath,多個值之間的變化實現動畫。

2、屬性解析:

  • values:就是上述的NSArray對象。裡面的元素稱為”關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀。
  • path:可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那麼values將被忽略。
  • keyTimes:可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的。

 

3、 與CABasicAnimation的區別:

  •  CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值。CABasicAnimation可看做是最多只有2個關鍵幀的CAKeyframeAnimation。

4、代碼案例

#pragma mark - 關鍵幀:按方形路徑移動
- (IBAction)keyPathPath:(UIButton *)sender {
    
    //設置keyPath 為:position
    
    CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    //設置5個值
    NSValue * v1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 400)];
    NSValue * v3 =[NSValue valueWithCGPoint:CGPointMake(300, 400)];
    NSValue * v4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
    NSValue * v5 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    
    //加入“值”數組
    animation.values=@[v1,v2,v3,v4,v5];
    animation.duration=2;
    animation.repeatCount=CGFLOAT_MAX;
    animation.removedOnCompletion=NO;
    animation.fillMode=kCAFillModeForwards;
    
    [self.button.layer addAnimation:animation forKey:nil];
    
}


#pragma mark - 關鍵幀:size變化

- (IBAction)keyPathSize:(id)sender {
    
    //設置keyPath 為:bounds.size
    
    CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"];
    
    //設置三個值
    
    NSValue * v0 = [NSValue valueWithCGSize:CGSizeMake(100, 100)];
    NSValue * v1 = [NSValue valueWithCGSize:CGSizeMake(200, 200)];
    NSValue * v2 = [NSValue valueWithCGSize:CGSizeMake(100, 100)];
    
    animation.values=@[v0,v1,v2];
    animation.duration=0.5;
    animation.repeatCount=CGFLOAT_MAX;
    animation.removedOnCompletion=NO;
    animation.fillMode=kCAFillModeForwards;
    
    [self.button.layer addAnimation:animation forKey:nil];
    
}


#pragma mark - 關鍵幀:抖動

- (IBAction)keyPathShake:(id)sender {
    
    //設置keyPath 為:transform.rotation.z
    
    CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    
    //設置兩個角度值
    NSNumber * n1 = @(-M_PI_4/3);
    NSNumber * n2 = @(M_PI_4/3);
    //再三個值之間進行改變
    animation.values=@[n1,n2,n1,];
    animation.repeatCount=CGFLOAT_MAX;
    animation.duration=0.15;
    animation.removedOnCompletion=NO;
    animation.fillMode=kCAFillModeForwards;
    [self.button.layer addAnimation:animation forKey:nil];
    
}

 

六、CAAnimationGroup 組動畫

 

1、定義:

  • 組動畫,是CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層後,組中所有動畫對象可以同時並發運行。

 2、屬性解析:

  • animations:用來保存一組動畫對象的NSArray。
  • 默認情況下,一組動畫對象是同時運行的,也可以通過設置動畫對象的beginTime屬性來更改動畫的開始時間。

3、代碼案例

  給出一個組動畫和轉場動畫的基本配置案例

   效果:

    

 

#pragma mark - 組動畫

- (IBAction)groupAnimation:(UIButton *)sender {
    
    [self makeView:nil];
    
    //動畫1:移動
    CAKeyframeAnimation * animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    NSValue * v1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 400)];
    NSValue * v3 = [NSValue valueWithCGPoint:CGPointMake(300, 400)];
    NSValue * v4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
    NSValue * v5 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    animation1.values=@[v1,v2,v3,v4,v5];
    animation1.repeatCount=CGFLOAT_MAX;
    animation1.removedOnCompletion=NO;
    animation1.fillMode=kCAFillModeForwards;
    
    //動畫2 :
    
    CAKeyframeAnimation * animation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    NSNumber * n1 = @(-M_PI_4/2);
    NSNumber * n2 = @(M_PI_4/2);
    animation2.values=@[n1,n2,n1,];
    animation2.repeatCount=CGFLOAT_MAX;
    animation2.duration=0.15;
    animation2.removedOnCompletion=NO;
    animation2.fillMode=kCAFillModeForwards;
    
    //創建組動畫
    
    CAAnimationGroup * animation = [CAAnimationGroup animation];
    animation.animations=@[animation1,animation2];
    animation.duration=2;
    animation.repeatCount=CGFLOAT_MAX;
    
    //將組動畫加入到layer就可以了,各個動畫並發執行
    [self.button.layer addAnimation:animation forKey:nil];
    
}

 

 

七、CATransition 轉場動畫

 

1、定義:

  轉場動畫,CAAnimation的子類,用於做頁面跳轉時的轉場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。UINavigationController就是通過CATransition實現了將控制器的視圖推入屏幕的動畫效果。這些動畫的效果系統已經寫好,我們只要配置一些屬性即可。

 

2、屬性解析:

  • type:               動畫過渡類型
  • subtype:         動畫過渡方向
  • startProgress:動畫起點(在整體動畫的百分比)
  • endProgress:  動畫終點(在整體動畫的百分比)

3、代碼案例(這裡把下面的UIView動畫一起實現,方便比較)

 

#pragma mark - 轉場動畫

-(void)makeImage
{
    
    //生成一個測試轉場動畫的視圖
    
    UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1"]];
    imageView.center =self.view.center;
    self.imageView=imageView;
    [self.view addSubview: imageView];
    
    //創建手勢識別器,用來響應屏幕滑動
    UISwipeGestureRecognizer * swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeImage:)];
    UISwipeGestureRecognizer * swipeRight =[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeImage:)];
    //添加識別器屬性
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    
    //添加到視圖
    
    [self.view addGestureRecognizer:swipeLeft];
    [self.view addGestureRecognizer:swipeRight];
    
}

#pragma mark - 滑動屏幕響應事件

-(void)swipeImage:(UISwipeGestureRecognizer *)rec
{
    
    //判斷滑動方向
    //向左滑動
    if (rec.direction==UISwipeGestureRecognizerDirectionLeft) {
        self.index++;
        //圖片可以循環播放
        if (self.index==6) {
            self.index=1;
        }
    }
    
    //向右滑動
    else{
        self.index--;
        if (self.index==0) {
            self.index=5;
        }
    }
    
#pragma mark - 方式一,使用過CATransition實現轉場(漸變消失)
    
    //這裡的changeStyle只是點擊按鈕的判斷
    if (self.changeStyle==1) {
        
        //創建動畫
        
        CATransition * animation = [CATransition animation];
        
        //前一張消失
        animation.type = kCATransitionFade;
        
        //將動畫添加到控件layer,控件屬性變化時(圖片更換)將采用設定動畫
        [self.imageView.layer addAnimation:animation forKey:nil];
        
    }
    
#pragma mark - 方式二 ,使用UIView(block)實現轉場(向左拖:左右旋轉+ 向右拖:上下翻頁)
    else if(self.changeStyle==2) {
        
        //如果向左滑動,向左旋轉顯示
        
        if (rec.direction==UISwipeGestureRecognizerDirectionLeft) {
            
            [UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
                
               //block裡面是控件的屬性變化,這裡和CATransition實現不同
                UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
                self.imageView.image=image;
                
                
            } completion:nil];
        }
        
        //如果向右滑動,子頁面向下推出
        
        else{
            [UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{
                
                UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
                self.imageView.image=image;
                
            } completion:nil];
            
        }
    }
    
    
    
    
#pragma mark - 方式三,使用過CATransition實現轉場(向左滑:向左退出 + 向右滑:向下推出)
    else{
        
        CATransition * animation = [CATransition animation];
        //如果向右滑動,子頁面從左推出
        if (rec.direction == UISwipeGestureRecognizerDirectionRight) {
            animation.subtype = kCATransitionFromBottom;
            
        }
        //如果向右滑動,子頁面從下推出
        
        else{
            animation.subtype = kCATransitionFromRight;
            
        }
        
        animation.type = kCATransitionPush;
        
        [self.imageView.layer addAnimation:animation forKey:nil];
        
    }
    
    UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
    
    //這是添加了動畫的控件,屬性改變時按照我們設定的有動畫效果
    self.imageView.image=image;
    
}

 

 

八、UIView block動畫———(也可實現轉場動畫)

 

1、定義:

   UIKit框架直接將動畫集成到UIView類中,當內部的一些屬性發生改變時,UIView將為這些改變提供動畫支持。

 

2、UIView動畫的幾種類別:

 (1)三種block方式實現:所謂block方式,就是將改變視圖屬性的代碼寫在block中,實現動畫

  • + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion  

    參數解析:

    duration:   動畫的持續時間 

    delay:    動畫延遲delay秒後開始  

    options:   動畫的節奏控制

    animations: 將改變視圖屬性的代碼放在這個block中

    completion: 動畫結束後,會自動調用這個block

  • + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

     參數解析:

    duration:   動畫的持續時間

    view:     需要進行轉場動畫的視圖

    options:    轉場動畫的類型

    animations:  將改變視圖屬性的代碼放在這個block中

    completion:  動畫結束後,會自動調用這個block

  • + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion

     方法調用完畢後,相當於執行了下面兩句代碼:

    // 添加toView到父視圖

      [fromView.superview addSubview:toView]; 

    // 把fromView從父視圖中移除

      [fromView.superview removeFromSuperview];

    參數解析:

    duration:   動畫的持續時間

    options:   轉場動畫的類型

    animations:  將改變視圖屬性的代碼放在這個block中

    completion:  動畫結束後,會自動調用這個block

(2)首尾式動畫等(下文單獨介紹)。

 

九、UIView 首尾式動畫

 

1、定義:

  UIView的另一種實現動畫方式。

2、執行方式:

  執行動畫所需要的工作由UIView類自動完成,但仍要在希望執行動畫時通知視圖,為此需要將改變屬性的代碼放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之間,俗稱首尾式動畫。

 

3、常見方法解析:

  • + (void)setAnimationDelegate:(id)delegate

  設置動畫代理對象,當動畫開始或者結束時會發消息給代理對象

  • + (void)setAnimationWillStartSelector:(SEL)selector

  當動畫即將開始時,執行delegate對象的selector,並且把beginAnimations:context:中傳入的參數傳進selector

  • + (void)setAnimationDidStopSelector:(SEL)selector

  當動畫結束時,執行delegate對象的selector,並且把beginAnimations:context:中傳入的參數傳進selector

  • + (void)setAnimationDuration:(NSTimeInterval)duration

  動畫的持續時間,秒為單位

  • + (void)setAnimationDelay:(NSTimeInterval)delay

  動畫延遲delay秒後再開始

  • + (void)setAnimationStartDate:(NSDate *)startDate

  動畫的開始時間,默認為now

  • + (void)setAnimationCurve:(UIViewAnimationCurve)curve

  動畫的節奏控制,具體看下面的”備注”

  • + (void)setAnimationRepeatCount:(float)repeatCount

  動畫的重復次數

  • + (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses

  如果設置為YES,代表動畫每次重復執行的效果會跟上一次相反

  • + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache

  設置視圖view的過渡效果, transition指定過渡類型, cache設置YES代表使用視圖緩存,性能較好

 

九、UIImageView的幀動畫

 

1、定義:

  UIImageView可以讓一系列的圖片在特定的時間內按順序顯示。

2、屬性解析:

  • animationImages:要顯示的圖片(一個裝著UIImage的NSArray)
  • animationDuration:完整地顯示一次animationImages中的所有圖片所需的時間
  • animationRepeatCount:動畫的執行次數(默認為0,代表無限循環)

3、方法解析:

  • - (void)startAnimating;  開始動畫
  • - (void)stopAnimating;  停止動畫
  • - (BOOL)isAnimating;   是否正在運行動畫

 

十、UIActivityIndicatorView 轉輪動畫

 

1、定義:

   是一個旋轉進度輪,可以用來告知用戶有一個操作正在進行中,一般用initWithActivityIndicatorStyle初始化(之前的文章有做介紹)。

 2、方法解析:

  • - (void)startAnimating; 開始動畫
  • - (void)stopAnimating;  停止動畫
  • - (BOOL)isAnimating;  是否正在運行動畫
  • UIActivityIndicatorViewStyle  有3個值可供選擇:

UIActivityIndicatorViewStyleWhiteLarge    //大型白色指示器    

    UIActivityIndicatorViewStyleWhite             //標准尺寸白色指示器    

    UIActivityIndicatorViewStyleGray               //灰色指示器,用於白色背景

 

總結:

一款優秀的app離不開良好的用戶體驗,在現在用戶越來越挑剔,設計模式越來越成熟和泛濫的情況下,第一時間抓住用戶的眼球,自然是會獲得更高的成功率。另外,界面的多元化,也帶來了很多其他的使用功能,在賞心悅目的同時,也增加了app的功能擴展。所以,在膜拜大神們華麗設計的同時,自己也不妨嘗試給自己的設計加點花樣。。有了畫筆,剩下的靠自己~

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved