【Objective-c】アニメ学習ノート(三)CABasicAnimation

6357 ワード

前言:iOSはMacOSの座標系とは異なり、iOSは左手座標系、座標原点は左上角、MacOSは右手座標系、原点は左下角を使用しています.
単純なアニメーションインプリメンテーションかんたんなあにめーしょん:長方形のパンアニメーションちょうほうけいのパンあにめーしょん
- (void)viewDidLoad {
    [super viewDidLoad];
    //1.    layer
    CALayer *mylayer = [CALayer layer];
    //2.  layer  
    mylayer.bounds = CGRectMake(0, 0, 50, 80);
    mylayer.backgroundColor = [UIColor yellowColor].CGColor;
    mylayer.position = CGPointMake(50, 50);
    mylayer.anchorPoint = CGPointMake(0, 0);
    mylayer.cornerRadius = 20;
    //3.  layer
    [self.view.layer addSublayer:mylayer];
    self.mylayer = mylayer;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //1.      (  )
    CABasicAnimation *anima = [CABasicAnimation animation];
    //            
    //    layer position  ,   
    anima.keyPath = @"position";
    anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
    //                  
    anima.removedOnCompletion = NO;
    //              
    anima.fillMode = kCAFillModeForwards;
    
    //2.       layer(    )
    [self.mylayer addAnimation:anima forKey:nil];

}

ここに重要な知識点があります:positionとanchorPoint、分からないのはこのブログの頭の大きい青年を閲覧することができて、一瞬にして分かります.ここで私の理解を簡単に説明します:1つのlayerの位置frameはpositionとanchorPointが共同で決定した(layerの前のframeがいくらであれ影響しない)1つの変化があれば、layerの位置は変わります.2つ目はpositionとanchorPointが異なる座標系の重ね合わせ点であり、同じ点を指す.
アニメーションの実行プロセスをリスニングし、上のコードに基づいてエージェントを追加するように設定します.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //1.      (  )
    CABasicAnimation *anima = [CABasicAnimation animation];
    //            
    //    layer position  ,   
    anima.keyPath = @"position";
    anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
    //                  
    anima.removedOnCompletion = NO;
    //              
    anima.fillMode = kCAFillModeForwards;
    //        
    anima.delegate = self;
    NSString *str = NSStringFromCGPoint(self.myLayer.position);
    NSLog(@"   :%@",str);

    //2.       layer(    )
    [self.mylayer addAnimation:anima forKey:nil];
}

- (void)animationDidStart:(CAAnimation*)anim{
  NSLog(@"      ");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
  NSString *str = NSStringFromCGPoint(self.myLayer.position);
  NSLog(@"   :%@",str);
}
/*
     : 
**2016-12-01 23:50:47.172 CAPropertyAnimationDemo[2829:99758] ****     :****{50, 50}**
**2016-12-01 23:50:47.173 CAPropertyAnimationDemo[2829:99758] ****       **
**2016-12-01 23:50:47.423 CAPropertyAnimationDemo[2829:99758] ****     :****{50, 50}**
*/

上記の例から、アニメーション実行後のレイヤの状態を維持しても、実質的にレイヤの属性値はアニメーション実行前の初期値であり、実際には変更されていない.前例のpositionのように
CABasicAnimationには、autoreversesとrepeatCountという重要な属性のセットがあります.Autotoreversesが自動的にアニメーションを元の状態に逆方向に実行するかどうか、実行時間は順方向アニメーションの持続時間と一致します.repeatCountがアニメーションを繰り返すかどうか.この2つのアトリビュートの既定値はNOです.
パン、ズーム、回転
#import "ViewController.h"
@interface ViewController ()

@property (nonatomic,strong) CALayer *mylayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.    layer
    CALayer *mylayer = [CALayer layer];
    //2.  layer  
    mylayer.bounds = CGRectMake(0, 0, 50, 80);
    mylayer.backgroundColor = [UIColor yellowColor].CGColor;
    mylayer.position = CGPointMake(50, 50);
    mylayer.anchorPoint = CGPointMake(0, 0);
    mylayer.cornerRadius = 20;
    //3.  layer
    [self.view.layer addSublayer:mylayer];
    self.mylayer = mylayer;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//    [self keyPathWithPositionAnimation];
//    [self keyPathWithBoundsAnimation];
//    [self keyPathWithTransformAnimation];
    [self positionByTransformAnimation];
}

#pragma mark -     
- (void)keyPathWithPositionAnimation{
    //1.      (  )
    CABasicAnimation *anima = [CABasicAnimation animation];
    //            
    //    layer position  ,   
    //    :          "fromValue"  ,          
    anima.keyPath = @"position";
    anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
    anima.duration = 2;
    //                  
    anima.removedOnCompletion = NO;
    //              
    anima.fillMode = kCAFillModeForwards;
    anima.delegate = self;
    NSString *string = NSStringFromCGRect(self.mylayer.frame);
    NSLog(@"     :%@",string);
    
    //2.       layer(    )
    [self.mylayer addAnimation:anima forKey:nil];
}

#pragma mark -   
- (void)keyPathWithBoundsAnimation{
    //1.    
    CABasicAnimation *anima = [CABasicAnimation animation];
    anima.keyPath = @"bounds";
    //1.1        
    anima.duration = 2.0;
    //1.2           
    anima.removedOnCompletion = NO;
    anima.fillMode = kCAFillModeForwards;
    //1.3    ,    
    anima.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
    //2.0     layer
    [self.mylayer addAnimation:anima forKey:nil];
}

#pragma mark -   
- (void)keyPathWithTransformAnimation{
    CABasicAnimation *anima = [CABasicAnimation animation];
    anima.keyPath = @"transform";
    anima.duration = 2.0;
    anima.removedOnCompletion = NO;
    anima.fillMode = kCAFillModeForwards;
    anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2+M_PI_4, 1, 1, 0)];
    [self.mylayer addAnimation:anima forKey:nil];
}

#pragma mark -         
- (void)positionByTransformAnimation{
    CABasicAnimation *anima = [CABasicAnimation animation];
    anima.keyPath = @"transform";
    anima.duration = 2.0;
    anima.removedOnCompletion = NO;
    anima.fillMode = kCAFillModeForwards;
    
    anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 100, 1)];
    
    [self.mylayer addAnimation:anima forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim{
    NSLog(@"       ");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    NSString *string = NSStringFromCGRect(self.mylayer.frame);
    NSLog(@"     :%@",string);
}

完全なDemo