iOS學習筆記09-核心動畫CoreAnimation

1、CALayer

CALayer包含在QuartzCore框架中,具備跨平臺性,在iOS中使用Core Animation開發動畫的本質是 將CALayer內容轉化爲位圖從而供硬件操做併發

CALayer圖層是依附於UIView的

經常使用屬性:
屬性 描述
anchorPoint 和中心position重合的點,稱爲錨點,範圍在(0~1,0~1)
position 圖層中心點位置,至關於UIView的center
bounds 圖層大小
opacity 透明度,至關於UIView的alpha
建立自定義CALayer:
//自定義圖層
CALayer *layer = [[CALayer alloc] init];
layer.bounds = CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT);
layer.position = CGPointMake(160, 200);
layer.backgroundColor = [UIColor redColor].CGColor;
layer.cornerRadius = PHOTO_HEIGHT/2;
//注意僅僅設置圓角,對於圖形而言能夠正常顯示,可是對於圖層中繪製的圖片沒法正確顯示,當繪製一張圖片到圖層上的時候會從新建立一個圖層添加到當前圖層
//若是想要正確顯示則必須設置masksToBounds = YES,剪切子圖層
layer.masksToBounds = YES;
//設置邊框
layer.borderColor = [UIColor whiteColor].CGColor;
layer.borderWidth = 2;
//設置圖層代理
layer.delegate = self;
//添加圖層到根圖層
[self.view.layer addSublayer:layer];
//調用圖層setNeedDisplay,不然代理方法不會被調用
[layer setNeedsDisplay];

注意:陰影效果沒法和masksToBounds同時使用,由於masksToBounds的目的就是剪切外邊框,而陰影效果恰好在外邊框框架

2、Core Animation

Core Animation的類結構圖

  1. CAAnimation核心動畫的基類,不能直接使用,負責動畫運行時間、速度的控制,自己實現了CAMediaTiming協議。
  2. CAPropertyAnimation屬性動畫的基類(經過屬性進行動畫設置,注意是可動畫屬性),不能直接使用。
  3. CAAnimationGroup動畫組,動畫組是一種組合模式設計,能夠經過動畫組來進行全部動畫行爲的統一控制,組中全部動畫效果能夠併發執行。
  4. CATransition轉場動畫,主要經過濾鏡進行動畫效果設置。
  5. CABasicAnimation基礎動畫,經過屬性修改進行動畫參數控制,只有初始狀態和結束狀態。
  6. CAKeyframeAnimation關鍵幀動畫,一樣是經過屬性進行動畫參數控制,可是同基礎動畫不一樣的是它能夠有多個狀態控制。

1. 基礎動畫CABasicAnimation

基礎動畫建立通常分爲如下幾步:

①. 初始化動畫並設置動畫屬性
②. 設置動畫屬性初始值(能夠省略)、結束值以及其餘動畫屬性
③. 給圖層添加動畫動畫

咱們先來說個移動動畫實例:
#pragma mark 移動動畫
-(void)translatonAnimation:(CGPoint)location{    
    //1.建立動畫並指定動畫屬性    
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];        
    //2.設置動畫屬性初始值和結束值
    basicAnimation.fromValue = [NSValue valueWithCGPoint:CGPointZero];   
    basicAnimation.toValue = [NSValue valueWithCGPoint:location];
    //設置其餘動畫屬性
    basicAnimation.delegate = self;//設置代理    
    basicAnimation.duration = 3.0;//動畫時間3秒    
    //basicAnimation.repeatCount = HUGE_VALF;//設置重複次數,HUGE_VALF可看作無窮大    
    //basicAnimation.removedOnCompletion = NO;//運行一次是否移除動畫    
    //3.添加動畫到圖層,注意key至關於給動畫進行命名,之後得到該動畫時可使用此名稱獲取    
    [_layer addAnimation:basicAnimation forKey:@"MYBasicAnimation_Translation"];
}

執行上面的移動動畫,會出現一個現象,那就是 動畫結束後圖層回到原來位置 ,這是爲何呢?設計

由於圖層動畫的本質是圖層內部的內容轉化爲位圖,通過硬件操做造成的動畫效果,其實圖層自己在動畫過程當中沒有發生任何變化。3d

理解圖

要怎麼作才能解決這個問題呢?答案就是CAAnimation代理!!
#pragma mark - 動畫代理方法
#pragma mark 動畫開始
-(void)animationDidStart:(CAAnimation *)anim{
    if( [anim isKindOfClass:[CABasicAnimation class]] ) {
        CABasicAnimation *baseAnima = (CABasicAnimation *)anim;
        //使用key-value的方式保持終點位置座標
        [baseAnima setValue:baseAnima.toValue forKey:@"MTBasicAnimationLocation"];
    }
}
#pragma mark 動畫結束
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if( flag ) {
        //取出終點位置座標,進行設置
        _layer.position = [[anim valueForKey:@"MTBasicAnimationLocation"] CGPointValue];
    }
}

但這樣執行後又會出現另一個問題,那就是動畫結束後它有一個先回到起點再移動到終點的短暫動畫效果,這是什麼緣由呢?代理

隱式動畫致使的,對於非根圖層,設置圖層的可動畫屬性會產生自動動畫效果(例如position,實際上除了frame,其餘屬性都是可動畫屬性),這種動畫效果稱爲隱式動畫code

  • 補充: 也許有人問了,那咱們以前那麼費力加CABasicAnimation作動畫幹嗎,直接設置圖層position不就能夠實現了嗎?答案是這種隱式動畫咱們很差控制動畫時間等動畫屬性,它是系統自動幫咱們實現的過渡動畫效果。

在這裏咱們要消除這種問題的話,可使用事務CATransaction暫時消除隱式動畫,只須要修改動畫結束的代理方法:orm

#pragma mark 動畫結束
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if( flag ) {
        [CATransaction begin];//開啓事務
        [CATransaction setDisableActions:YES];//禁止隱式動畫
        _layer.position = [[anim valueForKey:@"MTBasicAnimationLocation"] CGPointValue];
        [CATransaction commit];//提交事務
    }
}

關於事務CATransaction和這節主題不太相關,就不細講,有興趣能夠本身去蘋果官方文檔查看具體使用方式對象

除了改變位置,還能夠改變其餘形變屬性,下面是旋轉動畫的實例
#pragma mark 旋轉動畫
-(void)rotationAnimation{    
    //1.建立動畫並指定動畫屬性    
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];    
    //2.設置動畫屬性初始值、結束值    
    basicAnimation.fromValue = [NSNumber numberWithFloat:M_PI_2];    
    basicAnimation.toValue = [NSNumber numberWithFloat:M_PI_2*3];    
    //設置其餘動畫屬性    
    basicAnimation.duration = 6.0;    
    basicAnimation.autoreverses = true;//旋轉後再旋轉到原來的位置    
    //4.添加動畫到圖層,注意key至關於給動畫進行命名,之後得到該動畫時可使用此名稱獲取    
    [_layer addAnimation:basicAnimation forKey:@"MYBasicAnimation_Rotation"];
}

2. 關鍵幀動畫CAKeyframeAnimation

關鍵幀動畫開發有2種方式:
  1. 經過 設置不一樣的屬性值 進行關鍵幀控制
  2. 經過 繪製路徑 進行關鍵幀控制

下面是實例:blog

#pragma mark 關鍵幀動畫第一種方式
-(void)translationAnimation1{    
    //1.建立關鍵幀動畫並設置動畫屬性    
    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];    
    //2.設置關鍵幀,這裏有四個關鍵幀,對於關鍵幀動畫初始值不能省略
    NSValue *key1 = [NSValue valueWithCGPoint:_layer.position];    
    NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(80, 220)];    
    NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(45, 300)];    
    NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(55, 400)];    
    NSArray *values = @[key1,key2,key3,key4];    
    keyframeAnimation.values = values;    
    //設置其餘屬性    
    keyframeAnimation.duration = 8.0;    
    keyframeAnimation.beginTime = CACurrentMediaTime() + 2;//設置延遲2秒執行    
    //3.添加動畫到圖層,添加動畫後就會執行動畫    
    [_layer addAnimation:keyframeAnimation forKey:@"MYKeyframeAnimation_Position1"];
}
#pragma mark 關鍵幀動畫第二種方式
-(void)translationAnimation2{    
    //1.建立關鍵幀動畫並設置動畫屬性    
    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];    
    //2.設置路徑    
    //繪製貝塞爾曲線    
    CGPathRef path = CGPathCreateMutable();    
    CGPathMoveToPoint(path, NULL, _layer.position.x, _layer.position.y);//移動到起始點    
    CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 55, 400);//繪製二次貝塞爾曲線    
    keyframeAnimation.path = path;//設置path屬性    
    CGPathRelease(path);//釋放路徑對象    
    //設置其餘屬性    
    keyframeAnimation.duration = 8.0;    
    keyframeAnimation.beginTime = CACurrentMediaTime() + 2;//設置延遲2秒執行    
    //3.添加動畫到圖層,添加動畫後就會執行動畫    
    [_layer addAnimation:keyframeAnimation forKey:@"MYKeyframeAnimation_Position2"];
}

3. 動畫組CAAnimationGroup

就是多個動畫的組合,直接來代碼:

#pragma mark 建立動畫組
-(void)groupAnimation{
    //1.建立動畫組
    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    //2.設置組中的動畫和其餘屬性
    CABasicAnimation *basicAnimation = [self rotationAnimation];//基本動畫
    CAKeyframeAnimation *keyframeAnimation = [self translationAnimation];//關鍵幀動畫
    animationGroup.animations = @[basicAnimation,keyframeAnimation];
    animationGroup.delegate = self;
    //設置動畫時間,若是動畫組中動畫已經設置過動畫屬性,則再也不生效
    animationGroup.duration = 10.0;
    animationGroup.beginTime = CACurrentMediaTime() + 5;//延遲五秒執行
    //3.給圖層添加動畫
    [_layer addAnimation:animationGroup forKey:nil];
}

4. 轉場動畫CATransition

轉場動畫使用幾個步驟:

①. 建立轉場動畫
②. 設置轉場類型、子類型(可選)及其餘屬性
③. 設置轉場後的新視圖並添加動畫到圖層

轉場類型

轉場方向類型

直接上代碼:
#pragma mark 轉場動畫
-(void)transitionAnimation:(BOOL)isNext{
    //1.建立轉場動畫對象
    CATransition *transition = [[CATransition alloc] init];
    //2.設置轉場類型,注意對於蘋果官方沒公開的動畫類型只能使用字符串,並無對應的常量定義
    transition.type = @"cube";
    //設置轉場方向類型
    if (isNext) {
        transition.subtype = kCATransitionFromRight;
    }else{
        transition.subtype = kCATransitionFromLeft;
    }
    //設置動畫時常
    transition.duration = 1.0f;
    //3.設置轉場後的新視圖添加轉場動畫
    _imageView.image = [self getImage:isNext];
    [_imageView.layer addAnimation:transition forKey:@"KCTransitionAnimation"];
}

這個是水立方的轉場動畫效果圖,吊炸天

相關文章
相關標籤/搜索