Core Animation

Core Anitmation 是什么??

•Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍!
(使用之前要导入框架哦)添加QuartzCore.framework和引入对应的框架<QuartzCore/QuartzCore.h>
 
 
那使用Core Animation的基本步骤是什么??
1.初始化一个动画对象(CAAnimation)并设置一些动画相关属性
2.CALayer中很多属性都可以通过CAAnimation实现动画效果,包括:opacity、position、transform、bounds、contents等(可以在API文档中搜索:CALayer Animatable Properties)
3.添加动画对象到层(CALayer)中,开始执行动画
4.通过调用CALayer的addAnimation:forKey增加动画到层(CALayer)中,这样就能触发动画了。通过调用removeAnimationForKey可以停止层中的动画
5.Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程
 
下面我们现在来介绍一下动画类的祖宗类----CAAnimation
•CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
他都有那些属性呢?(红色代表来自CAMediaTiming协议的属性)
duration:动画的持续时间
repeatCount:重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT
repeatDuration:重复时间
–removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,同时还要设置fillMode为kCAFillModeForwards
fillMode:决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之后
beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
–timingFunction:速度控制函数,控制动画运行的节奏
–delegate:动画代理
 
下面来看一个demo~
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    
    CGPoint point = [touch locationInView:self.view];
    [self moveToPoint:point];
    
}

-(void)moveToPoint:(CGPoint)point{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"] ;
    // 1.设置目的点
    animation.toValue =[NSValue valueWithCGPoint:point];
    // 2.设置动画时长
    animation.duration =0.5;
    // 3.设置完成后删除动画
    animation.removedOnCompletion = NO;
    // 4.设置模式为向前填充
    animation.fillMode = kCAFillModeBoth;
    // 5.设置速度模式为先慢后快
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    // 6.设置开始时长延后1秒
    animation.beginTime  =CACurrentMediaTime() + 1;
    // 7.将动画添加到Layer上开始执行
    [_redview.layer addAnimation:animation forKey:nil];

}

将上述代码插入到一视图控制器中,点屏幕上点击一下看看效果~

下面看一下fillMode是干啥的

•fillMode属性值(要想fillMode有效,最好设置removedOnCompletion = NO)
kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
kCAFillModeBoth 这个其实就是上面两个的合成,动画加入之后在开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
 
•速度控制函数(CAMediaTimingFunction)
1.kCAMediaTimingFunctionLinear(线性):匀速
2.kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
3.kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
4.kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
 
 艹刚才写了一个小时的博客不小心让我给点没了😢😢
蛋疼屎
算了粘一下代码把,有时间再写😢😢
#pragma mark 暂停动画
- (void)pause
{
    // 记录停止瞬间的时间偏移量,取出当前动画定格对应的事件
    CFTimeInterval time = [_redView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 利用图层的timeOffset记录暂停的时间偏移量
    _redView.layer.timeOffset = time;
    
    NSLog(@"%f", time);
    
    // 将速度设置为0,可以停止动画
    _redView.layer.speed = 0.0;
}

#pragma mark 继续动画
- (void)resume
{
    // 恢复时间量
    CFTimeInterval pauseTime = _redView.layer.timeOffset;
    // 取当前媒体时间
    CFTimeInterval time = CACurrentMediaTime();
    // 计算时间差值
    CFTimeInterval offset = time - pauseTime;
    NSLog(@"%f", offset);
   
    // 设置图层动画的起始时间
    _redView.layer.beginTime = offset;
    _redView.layer.timeOffset = 0;
    
    // 恢复速度为1
    _redView.layer.speed = 1.0;
}

// 用户抬起手指,才会执行,通常会针对touchesMove中的处理,做一些收尾工作
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    
}

#pragma mark - 动画代理方法
- (void)animationDidStart:(CAAnimation *)anim
{
    NSLog(@"动画开始 %@", NSStringFromCGPoint(_redView.center));
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    CABasicAnimation *animation = (CABasicAnimation *)anim;
    
    // 动画结束后,修正视图的位置
    CGPoint point = [animation.toValue CGPointValue];
    _redView.center = point;

    NSLog(@"动画结束 %@ %@", NSStringFromCGPoint(_redView.center), animation.toValue);
}

#pragma mark - 动画方法
#pragma mark 旋转动画
- (void)rotation
{
    
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    
    _redView.layer.anchorPoint = CGPointMake(1, 1);
    
    // 设置旋转角度,转360
    anim.toValue = @(2 * M_PI);
    // 要无限循环转动,指定一个非常大的数值
    // 对于无限循环的动画,需要处理动画累加的问题
    anim.repeatCount = HUGE_VALF;
//    anim.repeatCount = MAXFLOAT;
    
    // 如果要退出到后台,再次回复的时候继续执行动画,需要设置removedOnCompletion = NO
    anim.removedOnCompletion = NO;
    
    anim.duration = 1.0f;
    
    [_redView.layer addAnimation:anim forKey:@"myRotation"];
}

#pragma mark 缩放动画
- (void)scale
{
    // 1. 实例化
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    
    // 2. toValue
    anim.toValue = @(2.0);
    anim.repeatCount = 3;
    // 自动反向执行动画
    anim.autoreverses = YES;
    
    anim.duration = 0.3f;
    
    [_redView.layer addAnimation:anim forKey:nil];
}

 

posted @ 2014-07-19 15:24  784692237  阅读(465)  评论(0编辑  收藏  举报