iOS CoreAnimationキーフレームアニメーションCAKeyframeAnimation


参考資料:http://www.cnblogs.com/kenshincui/p/3972100.html#autoid-3-0-0まとめ:
    効果:
     キーフレームアニメーション、キーフレームアニメーションはアニメーション制御の過程で開発者が主なアニメーション状態を指定し、各種状態間のアニメーションがどのように行われるかはシステム自動演算によって補完される(2つのキーフレーム間のシステムで形成されたアニメーションが補完アニメーションになる).このような動画の利点は、開発者がアニメーションフレームごとに、いくつかのキーフレームの状態だけに関心を持つ必要がないことである.
         キーフレームアニメーションの開発は、異なるアトリビュートを設定してキーフレーム制御する2つの形式に分かれています.
  
もう1つは、パスをペイントすることによってキーフレーム制御が行われ、後者の優先度が前者より高く、パスを設定するとプロパティが機能しなくなります.
キーフレームアニメーションを作成するには:
// 1.        
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    
    [keyAnimation setValue:[NSValue valueWithCGPoint:CGPointMake(50, 614) ]forKey:@"LayerPosition"];
    
    // 2.          
    CGMutablePathRef path = CGPathCreateMutable();
    //         
    CGPathMoveToPoint(path, NULL, _layer.position.x, _layer.position.y);
    
    
    
    //          
    //       ,
    CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 50, 400);
    CGPathAddCurveToPoint(path, NULL, 160, 500, -30, 600, 50, 614);
    //               
    keyAnimation.path = path;
    
/   //       
    CGPathRelease(path);
    
    
    keyAnimation.calculationMode = kCAAnimationCubic;
    
    //         
    keyAnimation.duration = 5.0;
    keyAnimation.removedOnCompletion = NO;
    keyAnimation.repeatCount = 1;
    
    keyAnimation.delegate = self;
    
    //        
    [_layer addAnimation:keyAnimation forKey:@"KCKeyAnimation_Positon"];
キーフレームアニメーションパスについて     パスがカーブでなければ、    矩形経路は、矩形の左上隅から運転を開始する、時計回りに1週間運転して最上角に戻る.    楕円経路は楕円の右側から(0度)時計回りに一周して右側に戻る.
キーフレームの各フレーム時間のプロパティについて
keyTimes          各キーフレームの時間制御.前にvaluesを使用して4つのキーフレームを設定しましたが、デフォルトでは2フレームごとの間隔は8/(4-1)秒です.1フレーム目から2ピン目までのアニメーションの所要時間を4秒、2フレーム目から3フレーム目までの時間を2秒、3フレーム目から4フレーム目までの時間を2秒制御したい場合はkeyTimesで設定できます.keyTimesには時間占有率ポイントが格納されています.この場合、keyTimesの値を0.0、0.5、0.75、1.0(もちろんNSNumberに変換する必要があります)、つまり1~2フレームが総時間の50%、2~3フレームが総時間の75%、3~4フレームが8秒で終了するように設定できます.
 caculationMode       アニメーション計算モード.また、keyValuesアニメーションの例としては、1フレーム目から8/3秒目から2フレーム目までを直接通過するのではなく、1フレームから2フレーム目までを一貫性のあるアニメーションにすることができるのは、アニメーションモードが連続しているためである    kCAAnimationLinearこれは計算モードのデフォルト値です    kCAAnimationDiscreteが離散すると、1フレーム目から8/3秒を経て2フレーム目に直接アニメーションが表示され、その間に移行はありません    kCAAnimationPaced(均一に実行するとkeyTimesは無視されます)、    kCAAnimationCubic(スムーズ実行、位置変動キーフレームアニメーションのトラックをスムーズに実行)    kCAAnimationCubicPaced(スムーズで均一に実行)
直接コードをつけて、簡単で分かりやすくて、注釈はとてもそろっています:
//
//  ViewController.m
//  CAKeyframeAnimation
//
//  Created by     on 16/5/26.
//  Copyright © 2016     . All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) CALayer *layer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    //     ()
    UIImage *backImage = [UIImage imageNamed:@"haha1"];
    self.view.backgroundColor = [UIColor colorWithPatternImage:backImage];
    
    //        
    _layer = [[CALayer alloc] init];
    _layer.bounds = CGRectMake(50, 50, 10, 20);
    _layer.position = CGPointMake(50, 150);
    _layer.contents = (id)[UIImage imageNamed:@"hudie"].CGImage;
    [self.view.layer addSublayer:_layer];
    
    //     
    [self translationKeyAnimation];
}


/**
 *       ,                            ,                        (                      ),                      ,               
    
                 ,                    
                     ,          ,                 

 */


/**
 *           
 
 *            , 
                    ,             .
                    (0 )         .
 */

/**
 *  keyTimes
 *      
              。    values        ,              :8/(4-1) 。                    4 ,           2 ,           2   ,     keyTimes    。keyTimes            ,      keyTimes   0.0,0.5,0.75,1.0(       NSNumber),    1 2        50%,2 3        75%,3 4    8   。
 

 */


/**
 *  caculationMode
 *
 *        。    keyValues    ,   1 2                1   8/3   2            
    kCAAnimationLinear           
    kCAAnimationDiscrete             1   8/3     2 ,        
    kCAAnimationPaced(    ,   keyTimes)、
    kCAAnimationCubic(    ,                  
    kCAAnimationCubicPaced(      )
 */
#pragma mark ---      ---->                
- (void)translationAnimation
{
    // 1.               keyPath
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    // 2.     ,  4    
    //                ,          
    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)];
    
    //   keyTimes             
    keyAnimation.keyTimes = @[@(0.1), @(0.2), @(0.3), @(1.0)];
    
    NSArray *keys = @[key1, key2, key3, key4];
    //      
    keyAnimation.values = keys;
    // 3.       
    keyAnimation.duration = 5.0;
    keyAnimation.repeatCount = HUGE_VALF;
    keyAnimation.removedOnCompletion = NO;
    
    //                 
    keyAnimation.beginTime = CACurrentMediaTime() + 2;
    
    // 4.       
    [_layer addAnimation:keyAnimation forKey:@"KCKeyframeAnimation_Position"];
    
}


#pragma mark ----       ---->                 
- (void)translationKeyAnimation
{
    // 1.        
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    
    [keyAnimation setValue:[NSValue valueWithCGPoint:CGPointMake(50, 614) ]forKey:@"LayerPosition"];
    
    // 2.          
    CGMutablePathRef path = CGPathCreateMutable();
    //         
    CGPathMoveToPoint(path, NULL, _layer.position.x, _layer.position.y);
    
    
    
    //          
    //       ,
    CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 50, 400);
    CGPathAddCurveToPoint(path, NULL, 160, 500, -30, 600, 50, 614);
    //               
    keyAnimation.path = path;
    
    CGPathRelease(path);
    
    
    keyAnimation.calculationMode = kCAAnimationCubic;
    
    //         
    keyAnimation.duration = 5.0;
    keyAnimation.removedOnCompletion = NO;
    keyAnimation.repeatCount = 1;
    
    keyAnimation.delegate = self;
    
    //        
    [_layer addAnimation:keyAnimation forKey:@"KCKeyAnimation_Positon"];
}

#pragma mark ---        
- (void)animationDidStart:(CAAnimation *)anim
{
    
}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    //      
    [CATransaction begin];
    
    //         
    [CATransaction setDisableActions:YES];
    
    _layer.position = [[anim valueForKey:@"LayerPosition"] CGPointValue];
    
    [CATransaction commit];
    
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end