美文网首页动画
CoreAnimtion 基础

CoreAnimtion 基础

作者: 张无忌_ | 来源:发表于2016-01-07 10:53 被阅读40次

    CoreAnimation是一组非常强大 的API,它可以做出来非常绚丽的动画效果,前边介绍了 CoreAnimation 的核心组件CALayer

    CAAnimation简介:是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类;

    常用的属性:

    属性说明:(红色代表来自CAMediaTiming协议的属性)

    duration:动画的持续时间

    repeatCount:重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT

    repeatDuration:重复时间

    removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards

    fillMode:决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之后

    beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间

    timingFunction:速度控制函数,控制动画运行的节奏

    delegate:动画代理

    话不多说,上代码:

    // 1. 初始化动画对象  基本动画

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];

    // 设置代理

    anim.delegate = self;

    // 2. 设置动画属性

    [anim setToValue:[NSValue valueWithCGPoint:toValue]];

    [anim setDuration:1.0f];

    // 4. 添加动画到图层

    [self.myView.layer addAnimation:anim forKey:nil];

    点击屏幕,动画执行完成,后又返回初始位置,怎么能让动画停留在最后点击位置呢? 这时候     fillMode    跟 removedOnCompletion  就派上用场了;

    anim.fillMode = kCAFillModeForwards; //逐渐逼近目标点

     anim.removedOnCompletion = NO;

    fillMode属性值(要想fillMode有效,最好设置removedOnCompletion = NO)

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

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

    kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。

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

    设置完之后,在运行,发现myView可以停留在手指点击后的位置了。  但是 很奇怪,  view的Frame没有任何变化  ,可以用

     NSLog(@"%@",NSStringFromCGRect(self.myView.frame));  

    在动画结束后,打印view的Frame观察

    想要解决这个问题,可以使用setValue:forKey:传值

    [anim setValue:[NSValue valueWithCGPoint:toValue] forKey:@"targetPoint1"];

    [anim setValue:@"translationTo" forKey:@"animationType"];

    然后在- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 中设置 value的cener属性,修改坐标。

    CGPoint targetPoint = [[anim valueForKey:@"targetPoint1"] CGPointValue];

    NSLog(@"tragetPoint:%@",NSStringFromCGPoint(targetPoint));

    完之后,在观察view的frame,  完美解决;

    起始UIView帮我们封装了CoreAnimation的基本动画, 使用起来也非常容易:

    [UIView animateWithDuration:1.0f animations:^{

    self.myView.center = location;

    } completion:^(BOOL finished) {

    NSLog(@"%@",NSStringFromCGRect(self.myView.frame));

    }];

    但是,只是封装了一些基本动画,  如果我们要实现比较复杂的动画(CAAnimationGroup),还是需要实现上面一坨代码。

    缩放动画示例:

    - (void)scaleAnim{

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

    anim.toValue = @0.5;

    anim.duration = 0.5;

    anim.autoreverses = YES;  //自动翻转

    [self.myView.layer addAnimation:anim forKey:nil];

    }

    旋转动画:

    - (void)rotationAnim{

    self.myView.layer.anchorPoint = CGPointMake(0.8, 0.8);

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

    //不停地旋转

    anim.toValue = @(2 * M_PI);

    anim.repeatCount = HUGE_VALF;

    anim.duration = 0.5;

    //对于循环播放的动画效果,一定要removedOnCompletion设置为 No

    anim.removedOnCompletion = NO;

    [self.myView.layer  addAnimation:anim forKey:@"rotationAnim"];

    }

    暂停动画:

    - (void)pauseAnim{

    //1. 取出当前的动画时间,要暂停的时间  CoreAnimation absolute time

    CFTimeInterval currentTime = [self.myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];

    //2. 将动画的运行速度设置 == 0    ==》动画默认的运行速度是 1.0 /速度的比例

    self.myView.layer.timeOffset = currentTime;

    //3. 设置动画的时间偏移量    =》 让动画定格在该时间点

    self.myView.layer.speed = 0.0f;

    }

    恢复动画:

    - (void)continueAnim{

    //1. 将动画的时间偏移量作为暂停时的时间点

    CFTimeInterval pauseTime = self.myView.layer.timeOffset;

    //2. 根据媒体时间计算出准确的启动动画时间  ,  对之前的暂停动画时间进行修正

    CFTimeInterval beginTime = CACurrentMediaTime() - pauseTime;

    //3. 设置图层的开始动画时间

    self.myView.layer.beginTime = beginTime;

    //4. 将timeOffset清空

    self.myView.layer.timeOffset = 0.0f;

    self.myView.layer.speed = 1.0f;

    }

    在appdelegate中获取controller的方法:

    ViewController *viewController =  (ViewController *)[application.windows.firstObject rootViewController];

    相关文章

      网友评论

        本文标题:CoreAnimtion 基础

        本文链接:https://www.haomeiwen.com/subject/kqjfkttx.html