CoreAnimation练习

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self test];
    [self test2];
    [self test3];
    [self test4];
    [self test5];
    [self test7];
}

//- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//    
//   
//}

#pragma mark - 小方块
- (void)test{
    
    
    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor orangeColor].CGColor;
    
    layer.delegate = self;
    
    [self.view.layer addSublayer:layer];
    layer.anchorPoint = CGPointMake(0.5, 0.5);
    
    layer.position = CGPointMake(100, 100);
    
    
    CABasicAnimation *ani = [[CABasicAnimation alloc] init];
    
    ani.keyPath = @"transform.scale";
    
    ani.fromValue = [NSNumber numberWithFloat:0.5];
    ani.toValue = [NSNumber numberWithFloat:1.8];
    
    ani.repeatCount = MAXFLOAT;
    ani.duration = 1.0f;

    // 当动画执行到toValue指定的状态时是从toValue的状态逆回去,还是直接跳到fromValue的状态再执行一遍
    ani.autoreverses = YES;
    
    ani.fillMode = kCAFillModeForwards;
    ani.removedOnCompletion = NO;
    
    [layer addAnimation:ani forKey:nil];
    
    
}

- (void)animationDidStart:(CAAnimation *)anim{
    NSLog(@"动画开始");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    NSLog(@"动画结束");
}

- (void)test2{
    
    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0, 0, 50, 50);
    layer.backgroundColor = [UIColor redColor].CGColor;
    
    layer.anchorPoint = CGPointMake(0, 0);
    layer.position = CGPointMake(0, 200);
    
    [self.view.layer addSublayer:layer];
    
    
    
    CABasicAnimation *ani = [[CABasicAnimation alloc] init];
    ani.keyPath = @"transform.translation.x";
    
    ani.fromValue = [NSNumber numberWithFloat:60];
    ani.toValue = [NSNumber numberWithFloat:300];
    
    ani.autoreverses = YES;
    
    ani.fillMode = kCAFillModeForwards;
    ani.removedOnCompletion = NO;
    
    ani.duration = 1;
    ani.repeatCount = MAXFLOAT;
    
    [layer addAnimation:ani forKey:nil];
    
    
}

- (void)test3{
    
    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0, 0, 50, 50);
    layer.backgroundColor = [UIColor blueColor].CGColor;
    layer.anchorPoint = CGPointMake(0.5, 0);
    layer.position = CGPointMake(100, 0);
    
    [self.view.layer addSublayer:layer];
    
    CABasicAnimation *ani = [[CABasicAnimation alloc] init];
    ani.keyPath = @"transform.translation.y";
    ani.fromValue = [NSNumber numberWithFloat:0];
    ani.toValue = [NSNumber numberWithFloat:self.view.frame.size.height - 50];
    
    ani.fillMode = kCAFillModeBoth;
    ani.removedOnCompletion = NO;
    
    ani.autoreverses = YES;
    
    ani.duration = 2;
    ani.repeatCount = MAXFLOAT;
    
    
    
    CABasicAnimation *ani2 = [[CABasicAnimation alloc] init];
    ani2.keyPath = @"transform.scale";
    ani2.fromValue = [NSNumber numberWithFloat:1];
    ani2.toValue = [NSNumber numberWithFloat:2.8];
    
    ani2.fillMode = kCAFillModeBoth;
    ani2.removedOnCompletion = NO;
    
    ani2.autoreverses = YES;
    
    ani2.duration = 1;
    ani2.repeatCount = MAXFLOAT;
    
    
    CABasicAnimation *ani3 = [[CABasicAnimation alloc] init];
    ani3.keyPath = @"transform.rotation.y";
    ani3.fromValue = [NSNumber numberWithFloat:1];
    ani3.toValue = [NSNumber numberWithFloat:M_PI_2*2];
    
    ani3.fillMode = kCAFillModeBoth;
    ani3.removedOnCompletion = NO;
    
    ani3.autoreverses = YES;
    
    ani3.duration = 0.5;
    ani3.repeatCount = MAXFLOAT;
    
    CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
    group.duration = 2;
    group.animations = @[ani,ani2,ani3];
    group.repeatCount = MAXFLOAT;
    group.autoreverses = YES;
    
    [layer addAnimation:group forKey:nil];
}

- (void)test5{
    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0, 0, 50, 50);
    layer.backgroundColor = [UIColor greenColor].CGColor;
    layer.anchorPoint = CGPointMake(0.5, 0);
    layer.position = CGPointMake(100, 0);
    
    [self.view.layer addSublayer:layer];
    
    CAKeyframeAnimation *ani = [[CAKeyframeAnimation alloc] init];
    ani.keyPath = @"position";
    CGPoint p1 = CGPointMake(80, 80);
    CGPoint p2 = CGPointMake(250, 80);
    CGPoint p3 = CGPointMake(250, 250);
    CGPoint p4 = CGPointMake(80, 250);
    CGPoint p5 = CGPointMake(80, 80);
//    ani.values = @[[NSValue valueWithCGPoint:p1],
//                   [NSValue valueWithCGPoint:p2],
//                   [NSValue valueWithCGPoint:p3],
//                   [NSValue valueWithCGPoint:p4],
//                   [NSValue valueWithCGPoint:p5]];
    
//    ani.keyTimes = @[@0.25,@0.25,@0.25,@0.25];
    CGMutablePathRef path = CGPathCreateMutable();
//    CGPathAddRect(path, NULL, CGRectMake(0, 0, 200, 200));
//    CGPathAddEllipseInRect(path, NULL, CGRectMake(0, 0, 200, 200));
    CGPathAddArc(path, NULL, 200, 200, 100, 0, 2*M_PI, YES);
//    CGPathMoveToPoint(path, NULL, 0, 0);
//    CGPathAddLineToPoint(path, NULL, 300, 300);
    ani.path = path;
    
    ani.duration = 2;
    ani.repeatCount = MAXFLOAT;
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
//    ani.autoreverses = YES;
    
    [layer addAnimation:ani forKey:nil];
    
    
}

- (void)test4{
    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0, 0, 50, 50);
    layer.backgroundColor = [UIColor grayColor].CGColor;
    layer.anchorPoint = CGPointMake(0.5, 0);
    layer.position = CGPointMake(100, 0);
    
    [self.view.layer addSublayer:layer];
    
    CASpringAnimation *ani = [[CASpringAnimation alloc] init];
    ani.keyPath = @"position";
    
    ani.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    ani.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 400)];
    //这个属性设置弹簧重物的质量 会影响惯性 必须大于0 默认为1
    ani.mass = 1;
    //设置弹簧的刚度系数,必须大于0 默认为100  这个越大 则回弹越快
    ani.stiffness = 50;
    //阻尼系数 默认为10 必须大于0 这个值越大 回弹的幅度越小
    ani.damping = 2.5;
    //初始速度
    ani.initialVelocity = 0;
    
    NSLog(@"ani.settlingDuration %lf",ani.settlingDuration);
    ani.duration = ani.settlingDuration;
    ani.repeatCount = MAXFLOAT;
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
    //    ani.autoreverses = YES;
    
    [layer addAnimation:ani forKey:nil];
    
    
}

- (void)test7{
    
//    CALayer *layer = [[CALayer alloc] init];
//    layer.bounds = CGRectMake(0, 0, 50, 50);
//    layer.backgroundColor = [UIColor grayColor].CGColor;
//    layer.anchorPoint = CGPointMake(0.5, 0.5);
//    layer.position = CGPointMake(self.view.frame.size.width - 80, 40);
//    
//    [self.view.layer addSublayer:layer];
    
    UIImageView *imgView = [[UIImageView alloc] init];
    imgView.frame = CGRectMake(self.view.frame.size.width - 120, 40, 100, 100);
    imgView.image = [UIImage imageNamed:@"通风"];
    [self.view addSubview:imgView];
    CALayer *layer = imgView.layer;
    layer.anchorPoint = CGPointMake(0.5, 0.5);
    
    
    CABasicAnimation *ani = [[CABasicAnimation alloc] init];
    ani.keyPath = @"transform.rotation.z";
    ani.fromValue = @0;
    ani.toValue = [NSNumber numberWithFloat:2*M_PI];
    
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
    ani.repeatCount = MAXFLOAT;
    
    ani.duration = 3;
    
    [layer addAnimation:ani forKey:nil];
    
    
}



@end

 

 

  • keyPath: 决定基础动画的类型,该值不能随便取,一旦取错就达不到想要的效果。要改变位置就取position,要改变透明度就取opacity,要等比例缩放就取transform.scale...更多key请看下面的表1,要尽量能记住这些内容

  • fromValue: 动画的起始状态值,虽然iOS文档给出的类型是id,不过这里应该传NSValue对象,比如NSNumber(NSNubmer继承自NSValue)。其具体含义

  • autoreverse: 当动画执行到toValue指定的状态时是从toValue的状态逆回去,还是直接跳到fromValue的状态再执行一遍

  • fileMode: fillMode的作用就是决定当前对象过了非active时间段的行为. 非active时间段是指动画开始之前以及动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用. 下面来讲各个fillMode的意义:

  1. kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态

  2. kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态

  3. kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态。因为有可能出现fromValue不是目前layer的初始状态的情况,如果fromValue就是layer当前的状态,则这个参数就没太大意义。

  4. kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.

 

posted @ 2016-04-18 08:30  人生路1/5  阅读(215)  评论(0编辑  收藏  举报