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)。其具體含義spa

  • autoreverse: 當動畫執行到toValue指定的狀態時是從toValue的狀態逆回去,仍是直接跳到fromValue的狀態再執行一遍code

  • fileMode: fillMode的做用就是決定當前對象過了非active時間段的行爲. 非active時間段是指動畫開始以前以及動畫結束以後。若是是一個動畫CAAnimation,則須要將其removedOnCompletion設置爲NO,要否則fillMode不起做用. 下面來說各個fillMode的意義:orm

  1. kCAFillModeRemoved 這個是默認值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到以前的狀態對象

  2. kCAFillModeForwards 當動畫結束後,layer會一直保持着動畫最後的狀態blog

  3. kCAFillModeBackwards 這個和kCAFillModeForwards是相對的,就是在動畫開始前,你只要將動畫加入了一個layer,layer便當即進入動畫的初始狀態。由於有可能出現fromValue不是目前layer的初始狀態的狀況,若是fromValue就是layer當前的狀態,則這個參數就沒太大意義。繼承

  4. kCAFillModeBoth 理解了上面兩個,這個就很好理解了,這個其實就是上面兩個的合成.動畫加入後開始以前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態.ip

相關文章
相關標籤/搜索