iOS:核心動畫之關鍵幀動畫CAKeyframeAnimation

CAKeyframeAnimation——關鍵幀動畫
關鍵幀動畫,也是CAPropertyAnimation的子類,與CABasicAnimation的區別是:
–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
 
具體的關鍵幀實例以下:
實例一:設置改變的屬性值爲透明度opacity,觸摸屏幕時,動畫開始執行,動畫執行過程當中,動畫的透明度逐漸變淺.結束時透明度恢復原狀。
代碼以下:
//聲明屬性
#import "ViewController.h"
@interface ViewController ()
@property (strong,nonatomic)CALayer *subLayer; //聲明核心動畫子層 @end
//建立核心動畫子層
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //建立子層
    self.subLayer = [CALayer layer];
    //設置子層大小
    self.subLayer.bounds = CGRectMake(0, 0, 100, 100);
    //設置子層的位置
    self.subLayer.position = CGPointMake(100, 100);
    //設置子層的背景顏色
    self.subLayer.backgroundColor = [[UIColor redColor]CGColor];
    //添加子層到根層
    [self.view.layer addSublayer:self.subLayer];
}
//處理觸摸事件
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //建立關鍵幀動畫
    CAKeyframeAnimation *keyframe = [[CAKeyframeAnimation alloc]init];
   //設置變化屬性值爲透明度
    keyframe.keyPath = @"opacity";

//設置每一幀動畫的透明度時刻值 keyframe.values
= @[@1.0,@0.5,@0.0,@0.5,@1.0];
//設置動畫持續事件 keyframe.duration
= 1.0f; //添加動畫到子層 [self.subLayer addAnimation:keyframe forKey:@"keyAnimation"]; //forkey:的參數能夠本身設置,就是一個標示符,區別開其餘的動畫 }
演示結果:
開始時:                              中間某一時刻:                   結束時:
 
實例二:設置改變的屬性值爲位置position,當在屏幕上連續觸摸5個點時,動畫開始按照這個5個點的鏈接直線運行。等到結束時,動畫就停在最終的位置上,不在恢復原狀。
代碼以下:
//聲明屬性
#import "ViewController.h"
#define MAX_CLICKED_NUM 4    //觸摸的最大次數
@interface ViewController ()
@property (strong,nonatomic)NSMutableArray *points;  //用於存放觸摸屏幕的次數
@property (strong,nonatomic)CALayer *subLayer;//聲明核心動畫子層
@end
//建立核心動畫子層
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //初始化
    self.points = [NSMutableArray array];
    
    //建立子層
    self.subLayer = [CALayer layer];
    self.subLayer.bounds = CGRectMake(0, 0, 100, 100);
    self.subLayer.position = CGPointMake(100, 100);
    self.subLayer.backgroundColor = [[UIColor redColor]CGColor];
    
    //添加子層到根層
    [self.view.layer addSublayer:self.subLayer];
    
}
//觸摸事件的處理(若是觸摸次數不夠5次,就存儲起來,達到5次時,建立幀動畫,並開始動畫)
//觸摸事件的處理
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //獲取當前觸摸點
    CGPoint location = [[touches anyObject]locationInView:self.view];
    
    //判斷當前的點的個數
    if (self.points.count < MAX_CLICKED_NUM)
    {
        //添加當前點
        [self.points addObject:[NSValue valueWithCGPoint:location]];
    }
    else
    {
        
        //建立關鍵幀動畫
        CAKeyframeAnimation *keyanimation = [[CAKeyframeAnimation alloc]init];
        
        //設置該變量爲位置position
        keyanimation.keyPath = @"position";
        
        //設置每一幀動畫的位置值
        keyanimation.values = self.points;
        
        //設置動畫持續時間
        keyanimation.duration = 3.0f;
        
        //設置動畫不在恢復原狀
        keyanimation.removedOnCompletion = NO;
        keyanimation.fillMode = kCAFillModeForwards;
        
        //設置代理
        keyanimation.delegate = self;
        
        //添加動畫到層
        [self.subLayer addAnimation:keyanimation forKey:@"keyanimation"];
    }
    
}
//實現動畫的協議方法
#pragma mark -動畫代理方法
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    //關閉隱式動畫
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    
    //停留在最後的位置
    self.subLayer.position = [[self.points lastObject]CGPointValue];
    
    //提交動畫事物
    [CATransaction commit];
    
    //刪除上一次動畫結束後保存的全部的數據
    [self.points removeAllObjects];
}
演示結果:點擊5次後,運動過程很差捕捉,就不截圖了
起點:                                                         終點: 
   
 
 
實例三:設置改變的屬性值爲位置position,在屏幕上繪製一條線,繪製結束後,動畫就沿着這條線開始動畫。等到結束時,動畫就停在最終的位置上,不在恢復原狀。
代碼以下:
//聲明屬性
#import "ViewController.h"

@interface ViewController ()
@property (strong,nonatomic)CALayer *subLayer;     //聲明核心動畫子層用做動畫層
@property (assign,nonatomic)CGMutablePathRef path; //聲明可變的繪圖路徑
@property (strong,nonatomic)CALayer *DrawLayer;    //聲明核心動畫子層用來繪圖層
@end
//建立兩個核心動畫子層,一個用來繪製運行線路,另外一個用來看成動畫層
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //建立繪圖子層
    self.DrawLayer = [CALayer layer];
    self.DrawLayer.bounds = self.view.bounds;
    self.DrawLayer.position = CGPointMake(0, 0);
    self.DrawLayer.anchorPoint = CGPointMake(0, 0);
    self.DrawLayer.backgroundColor = [[UIColor whiteColor]CGColor];

//設置繪圖子層的代理,它會調用協議中的繪圖方法 self.DrawLayer.
delegate = self; //添加繪圖子層 [self.view.layer addSublayer:self.DrawLayer]; //建立動畫子層 self.subLayer = [CALayer layer]; self.subLayer.bounds = CGRectMake(0, 0, 100, 100); self.subLayer.position = CGPointMake(100, 100); self.subLayer.backgroundColor = [[UIColor redColor]CGColor]; //添加動畫子層 [self.view.layer addSublayer:self.subLayer]; }
//處理觸摸點擊事件,設置繪製線路徑的起點
//觸摸點擊事件的處理
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //獲取當前觸摸點
    CGPoint location = [[touches anyObject]locationInView:self.view];
        
    //建立路經
    self.path = CGPathCreateMutable();
    
    //將當前點加到路徑中去
    CGPathMoveToPoint(self.path, NULL, location.x, location.y);
    
}
//處理觸摸移動事件,繪製一條路徑線到終點,此時繪圖子層調用setNeedDisplay方法繪圖
//觸摸移動事件的處理
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    //獲取當前觸摸點
    CGPoint location = [[touches anyObject]locationInView:self.view];
    
    //將當前點加到路徑中去
    CGPathAddLineToPoint(self.path, NULL, location.x, location.y);
    
    //讓繪圖子層繪圖
    [self.DrawLayer setNeedsDisplay];
}
//處理觸摸結束事件,繪製線路徑結束後,建立幀動畫,設置相關屬性並執行動畫
//觸摸結束事件的處理
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    //建立幀動畫
    CAKeyframeAnimation *keyAnimation = [[CAKeyframeAnimation alloc]init];
    
    //設置改變屬性值爲位置position
    keyAnimation.keyPath = @"position";
    
    //設置動畫路徑爲繪製的路徑
    keyAnimation.path = self.path;
    
    //設置動畫持續時間
    keyAnimation.duration = 3.0f;
    
    
    //設置動畫結束時保持不變,不在恢復原狀
    keyAnimation.removedOnCompletion = NO;
    keyAnimation.fillMode = kCAFillModeForwards;
    
    
    //設置幀動畫代理
    keyAnimation.delegate = self;
    
    
    //添加幀動畫到動畫子層
    [self.subLayer addAnimation:keyAnimation forKey:@"keyAnimation"];
}
//實現幀動畫協議方法,動畫結束後,釋放繪製路徑
#pragma mark -動畫代理方法
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    //釋放路徑
    CGPathRelease(self.path);
}
//重寫繪圖子層的繪圖方法-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx,繪圖子層代理會調用它繪圖
#pragma mark -UILayer畫圖方法
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    //添加路徑
    CGContextAddPath(ctx, self.path);
    
    //設置顏色
    CGContextSetStrokeColorWithColor(ctx, [[UIColor blueColor]CGColor]);
    
    //繪路徑
    CGContextDrawPath(ctx, kCGPathStroke);
}

運行結果以下:只給出起始位置和結束位置截圖,動畫過程很差捕捉,就不給出截圖了數組

開始時位置:                                                  繪製路徑後,動畫沿路徑運行結束位置:動畫

      

相關文章
相關標籤/搜索