iOS layer层关键帧动画

上次介绍了 UIview的block动画 ,
这次说一下 view的layer层的关键帧动画
layer层的动画相对于 view层的动画 会更轻量。
直接看代码 每一个属性的详细说明 见代码下面的表格

     //先创建一个view用于执行动画
    UIView * myview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    myview.layer.contents = (id)[UIImage imageNamed:@"123"].CGImage;
    myview.center = CGPointMake(CGRectGetWidth(self.view.frame)/2, CGRectGetHeight(self.view.frame)/2);
    /*
    //可以设置 动画的锚点。用于控制动画缩放,放大,移动的中心点
    //左上角
    myview.layer.anchorPoint = CGPointMake(0, 0);
    //中心
    myview.layer.anchorPoint = CGPointMake(0.5,0.5);
    //右下角
    myview.layer.anchorPoint = CGPointMake(1, 1);
    */
    [self.view addSubview:myview];

    //关键帧  单一动画
    CAKeyframeAnimation *keyAnima1=[CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    keyAnima1.duration =1;
    keyAnima1.values = @[@(0),@(M_PI/4),@(M_PI/2)];
    keyAnima1.keyTimes = @[@0.0,@0.1,@1.0];
    keyAnima1.fillMode=kCAFillModeForwards;
    keyAnima1.removedOnCompletion = NO;
    keyAnima1.repeatCount = 1;//或    keyAnima1.repeatDuration = 100;
    keyAnima1.beginTime = CACurrentMediaTime() + 1;
    keyAnima1.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    keyAnima1.delegate = self;
    [myview.layer addAnimation:keyAnima1 forKey:@"brushTransformAnimation"];

    //关键帧  组合动画
    //旋转动画
    CAKeyframeAnimation *keyAnima_group1=[CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    keyAnima_group1.values = @[@(M_PI/2),@(M_PI),@(M_PI * 2)];;
    //位置移动动画
    CAKeyframeAnimation *keyAnima_group2=[CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(myview.center.x,myview.center.y)];
    NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
    NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(150, 150)];
    keyAnima_group2.values= @[value1,value2,value3];
    //组合两个动画
    CAAnimationGroup * g = [CAAnimationGroup animation];
    g.animations = @[keyAnima_group1,keyAnima_group2];
    g.duration = 3;
    g.fillMode=kCAFillModeForwards;
    g.removedOnCompletion = NO;
    //再上一个动画执行完 在执行
    g.beginTime = CACurrentMediaTime() + 2;
    [myview.layer addAnimation:g forKey:@"g"];

    //关键帧 单一动画。设置关键帧的 path 而不是 value
    CAKeyframeAnimation * keyAnima2 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    keyAnima2.calculationMode = kCAAnimationPaced;
    keyAnima2.fillMode = kCAFillModeForwards;
    keyAnima2.removedOnCompletion = NO;
    keyAnima2.duration = 2;
    keyAnima2.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    keyAnima2.beginTime = CACurrentMediaTime() + 5;
    CGMutablePathRef curvedPath_3 = CGPathCreateMutable();
    CGPathMoveToPoint(curvedPath_3, NULL, 150, 150);
    CGPathAddArc(curvedPath_3, NULL,  100, 150, 50, 0 , M_PI*2 , NO);
    keyAnima2.path = curvedPath_3;
    CGPathRelease(curvedPath_3);
    [myview.layer addAnimation:keyAnima2 forKey:@"moveTheSquare"];

基本属性的说明

属性 说明
KeyPath 动画变化的属性,如动画的位置,大小,颜色的变化,详见“表1”
duration 动画执行的时间
repeatCount 重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT
repeatDuration a重复的时间
removedOnCompletion 默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
fillMode 决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之,详见“表2”
beginTime 开始时间
timingFunction 速度控制函数,控制动画运行的节奏 详见“表3”
values NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
keyTimes 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,例如keyAnima1.keyTimes = @[@0.0,@0.1,@0.5,@0.7,@1.0],keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的,keyTimes 是和 values一起的。
path 可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
delegate 动画代理,动画开始 和 动画完成

表1
KeyPath属性的设置详解:

属性值 说明
transform.scale x,y轴同比放大缩小. 对应的
transform.scale.x x轴放大缩小
transform.scale.y y轴放大缩小
transform.rotation或transform.rotation.z 沿z轴旋转
transform.rotation.x 沿x轴旋转
transform.rotation.y 沿y轴旋转
margin 边距变化
backgroundColor 背景颜色变化
cornerRadius 圆角变化
borderWidth 变得宽度变化
bounds 大小变化
contents 内容变化
contentsRect 内容大小变化
frame 大小变化
hidden 是否显示
mask mask层变化
masksToBounds ???(有知道的可以评论告诉我)
shadowColor 阴影颜色
shadowOffset 阴影位置
shadowOpacity 阴影透明度
shadowRadius 阴影圆角

备注:keyPath 对应的 “values” 数组内大多数存的是 NSNumber 对象 。position ,frame 等 存的是 NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 200)]; 这样的对象。


表2
fillMode属性的设置详解:

属性值 说明
kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
kCAFillModeBoth 这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态

表3
速度控制函数(CAMediaTimingFunction)设置详解:

属性值 说明
kCAMediaTimingFunctionLinear 线性,匀速,给你一个相对静态的感觉
kCAMediaTimingFunctionEaseIn 渐进,动画缓慢进入,然后加速离开
kCAMediaTimingFunctionEaseOut 渐出,动画全速进入,然后减速的到达目的地
kCAMediaTimingFunctionEaseInEaseOut 渐进渐出,动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为

动画的代理方法

方法名 说明
– (void)animationDidStart:(CAAnimation *)anim; 动画开始时调用
– (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; 动画结束时调用

CALayer上动画的暂停和恢复

#pragma mark 暂停CALayer的动画
-(void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

    // 让CALayer的时间停止走动
      layer.speed = 0.0;
    // 让CALayer的时间停留在pausedTime这个时刻
    layer.timeOffset = pausedTime;
}

#pragma mark 恢复CALayer的动画
-(void)resumeLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = layer.timeOffset;
    // 1. 让CALayer的时间继续行走
      layer.speed = 1.0;
    // 2. 取消上次记录的停留时刻
      layer.timeOffset = 0.0;
    // 3. 取消上次设置的时间
      layer.beginTime = 0.0;
    // 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime)
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    // 5. 设置相对于父坐标系的开始时间(往后退timeSincePause)
      layer.beginTime = timeSincePause;
}

猜你喜欢

转载自blog.csdn.net/lwq718691587/article/details/51241273