核心动画(CAKeyframeAnimation,CABasicAnimation)

一,核心动画常用的三种例子

view的核心动画其体现就是把view按照指定好的路径进行运动,针对的是view的整体。 [view.layer addAnimation:动画路径 forKey:@“绑定动画路径的键值”];

A,view的整体按照指定好的路径进行运动,里面的子view固定在view不动情况:

1)创建需要显示的动画路径(动画路径可以是UIBezierPath,也可以是某个参数或点坐标等,如果是后者,则常常设置fromValue和toValue,通过它们来确定动画路径)

CGPoint starPoint = CGPointMake(150, 200);

CGPoint endPoint  = CGPointMake(400,550);

//    CGPoint ancholPoint = CGPointMake(endPoint.x + (starPoint.x - endPoint.x)/2.0, endPoint.y);

UIBezierPath *animPath = [[UIBezierPath alloc] init];

[animPath moveToPoint:starPoint];

[animPath addLineToPoint:endPoint];

//    [animPath addQuadCurveToPoint:endPoint controlPoint:ancholPoint];

2)创建动画,把动画路径绑定到动画上去,并且配置一些其他动画属性;(路径时用到的是CAKeyframeAnimation)

CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

keyAnimation.path = animPath.CGPath;

keyAnimation.removedOnCompletion = NO;

keyAnimation.fillMode = kCAFillModeForwards;

keyAnimation.duration = 5.0f;

keyAnimation.repeatCount = MAXFLOAT;

keyAnimation.autoreverses = YES;

keyAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

3)设置动画代理并且绑定动画到遮盖上去

keyAnimation.delegate = self;

[view.layer addAnimation:keyAnimation forKey:@"keyAnim"];

或者(对于一些有规律简单的动画也可以使用CABasicAnimation)

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

keyAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(150, 200)];

keyAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(400,550)];

keyAnimation.removedOnCompletion = NO;

keyAnimation.fillMode = kCAFillModeForwards;

keyAnimation.duration = 5.0f;

keyAnimation.repeatCount = MAXFLOAT;

keyAnimation.autoreverses = YES;

keyAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

keyAnimation.delegate = self;

[view.layer addAnimation:keyAnimation forKey:@"keyAnim"];

B,view的图层进行渲染绘画情况:

1)创建CAShapeLayer图层,配置图层属性及添加到view的图层上去

CAShapeLayer *layer1 = [CAShapeLayer layer];

layer1.fillColor = [UIColor clearColor].CGColor;

layer1.strokeColor = [UIColor redColor].CGColor;

layer1.lineWidth = 5;

[view.layer addSublayer:layer1];

2)创建需要显示的动画路径,及绑定到新创建的图层上去(动画路径可以是UIBezierPath,也可以是某个参数或点坐标等,如果是后者,则常常设置fromValue和toValue)

UIBezierPath *path = [self bezierSinPathWithStartPoint:CGPointMake(0, 100) endPoint:CGPointMake(100, 100) topHeight:50];

[path closePath];

layer1.path = path.CGPath;

3)创建动画,把动画路径绑定到动画上去,并且配置一些其他动画属性;(路径时用到的是CAKeyframeAnimation)

CABasicAnimation * anima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

anima.fromValue = [NSNumber numberWithFloat:0.f];

anima.toValue = [NSNumber numberWithFloat:1.f];

anima.duration = 4.0f;

anima.repeatCount = MAXFLOAT;

anima.timingFunction = UIViewAnimationOptionCurveEaseInOut;

4)设置动画代理并且绑定动画到新创建的图层上去

anima.delegate = self;

[layer1 addAnimation:anima forKey:@"strokeEndAniamtion2"];

C,view内部图层进行动画显示(即view内容本身固定的,只是慢慢显示或慢慢消失又或者按照指定轨迹显示内容),此时单纯的核心动画是无法做到的。解决方法如下:

1)创建CAShapeLayer作为view的遮盖:

CAShapeLayer *maskLayer = [CAShapeLayer layer];

view.layer.mask = maskLayer;

2)创建需要显示的动画路径(动画路径可以是UIBezierPath,也可以是某个参数或点坐标等,如果是后者,则常常设置fromValue和toValue,通过它们来确定动画路径)

UIBezierPath *startPath =     ;

UIBezierPath *endPath =     ;

3)遮盖的路径等于最后稳定显示时的路径,这个必须写,因为如果不写则会出现瞬间闪烁的BUG

maskLayer.path = endPath.CGPath;

4)创建动画,把动画路径绑定到动画上去,并且配置一些其他动画属性;(路径时用到的是CAKeyframeAnimation)

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];

animation.duration = 1.0;

animation.fromValue = (__bridge id)starCycle.CGPath;//开始路径

animation.toValue   = (__bridge id)endCycle.CGPath;//结束路径

如果是单路径时,代码可以如下

// 关键路径动画

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

animation.path = path.CGPath;

[maskLayer addAnimation:animation forKey:@"position"];

5)设置动画代理并且绑定动画到遮盖上去

animation.delegate = self;

[maskLayer addAnimation:animation forKey:@"path"];

二,核心动画详述

ACABasicAnimation使用总结(CABasicAnimation是CAKeyframeAnimation里面的一种,CABasicAnimation用于只确定起点和终点或者是开始路径和结束路径的简单的放大缩小,平移,翻转,点与点,渲染等有规律的动画;CAKeyframeAnimation是用于设置一些比较复杂的动画,即可以随便自定义路径再绑定到path属性上去)

.fromValue = 起点值或者    .fromValue = (__bridge id)starCycle.CGPath;//开始路径

.toValue      = 终点值            .toValue      =  (__bridge id)endCycle.CGPath;//结束路径

一,实例化:animationWithKeyPath,keypath如必须是下面几个

CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

position.x

position.y

position.z

position 位置(中心点的改变) [NSValue valueWithCGPoint:CGPointMake(300, 300)];或者keyAnimation.path = path.CGPath;

cornerRadius         圆角的设置 @(50)

backgroundColor 背景颜色的变化 (id)[UIColor purpleColor].CGColor

bounds 大小,中心不变 [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];

contents 内容,比如UIImageView的图片 imageAnima.toValue = (id)[UIImage imageNamed:@"to"].CGImage;

opacity 透明度 @(0.7)

contentsRect.size.width 横向拉伸缩放 @(0.4)最好是0~1之间的

path 路径

locations

strokeEnd 从渲染开始到渲染结束

二,设定动画的属性和说明

duration             动画的时长

repeatCount     重复的次数。不停重复设置为 HUGE_VALF

repeatDuration    设置动画的时间。在该时间内动画一直执行,不计次数。

beginTime     指定动画开始的时间。从开始延迟几秒的话,设置为【CACurrentMediaTime() + 秒数】 的方式

timingFunction    设置动画的速度变化

autoreverses     动画结束时是否执行逆动画

fromValue     所改变属性的起始值

toValue         所改变属性的结束时的值

byValue             toValue = fromValue+byValue

speed                  动画的速度

speed 属性注意点:

speed 改变动画的速度 可以直接设置动画上的speed属性,这样只有这个动画速度。或者在layer上设置speed属性,这样在该视图上的所有动画都提速,该视图上的所有子视图上的动画也会提速。

(1) 如果设置动画时间为4s,speed设置为2,则动画只需2s即可执行完。

(2)如果同时设置了动画的speed和layer 的speed,则实际的speed为两者相乘。

transformAnima.fromValue = @(M_PI_2);或者 = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0,10, 0)];

transformAnima.toValue = @(M_PI);

transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

transformAnima.autoreverses = YES;

transformAnima.repeatCount = HUGE_VALF;

transformAnima.beginTime = CACurrentMediaTime() + 2;延迟2秒

十分注意:

1)//CATransform3DMakeTranslation(x,y,z)平移,那一个不为0则向那一个方向平移,X左Y下Z外为正方向;假如为(0,-10,0),则即是   将要动画的原点  在  原视图view原点   的上方10

2)如果animationWithKeyPath采用@"transform.rotation.y”样式,则fromValue,toValue,byValue采用@(数字或者角度);

如果animationWithKeyPath采用@"transform”样式,则fromValue,toValue,byValue采用[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 10, 0)];

3)防止动画结束后回到初始状态,只需设置removedOnCompletion、fillMode两个属性就可以了。

transformAnima.removedOnCompletion = NO;

transformAnima.fillMode = kCAFillModeForwards;

解释:为什么动画结束后返回原状态?

首先我们需要搞明白一点的是,layer动画运行的过程是怎样的?其实在我们给一个视图添加layer动画时,真正移动并不是我们的视图本身,而是 presentation layer 的一个缓存。动画开始时 presentation layer开始移动,原始layer隐藏,动画结束时,presentation layer从屏幕上移除,原始layer显示。这就解释了为什么我们的视图在动画结束后又回到了原来的状态,因为它根本就没动过。

这个同样也可以解释为什么在动画移动过程中,我们为何不能对其进行任何操作。

所以在我们完成layer动画之后,最好将我们的layer属性设置为我们最终状态的属性,然后将presentation layer 移除掉。

fillMode属性的理解

该属性定义了你的动画在开始和结束时的动作。默认值是 kCAFillModeRemoved。

kCAFillModeRemoved 设置为该值,动画将在设置的 beginTime 开始执行(如没有设置beginTime属性,则动画立即执行),动画执行完成后将会layer的改变恢复原状。

kCAFillModeForwards 设置为该值,动画即使之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性值是 YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO。

kCAFillModeBackwards 设置为该值,将会立即执行动画的第一帧,不论是否设置了 beginTime属性。观察发现,设置该值,刚开始视图不见,还不知道应用在哪里。

kCAFillModeBoth 该值是 kCAFillModeForwards 和 kCAFillModeBackwards的组合状态

三,添加动画

[self.imageView.layer addAnimation:transformAnima forKey:@"A"];一个 CABasicAniamtion 的实例对象只是一个数据模型,需要绑定到layer上去

组合动画的实现

CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];

positionAnima.fromValue = @(self.imageView.center.y);

positionAnima.toValue = @(self.imageView.center.y-30);

positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

transformAnima.fromValue = @(0);

transformAnima.toValue = @(M_PI);

transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

CAAnimationGroup *animaGroup = [CAAnimationGroup animation];

animaGroup.duration = 2.0f;

animaGroup.fillMode = kCAFillModeForwards;

animaGroup.removedOnCompletion = NO;

animaGroup.animations = @[positionAnima,transformAnima];

[self.imageView.layer addAnimation:animaGroup forKey:@"Animation"];

四,动画开始和结束时的事件

为了获取动画的开始和结束事件,需要实现协议 positionAnima.delegate = self;

代理方法实现

//动画开始时

- (void)animationDidStart:(CAAnimation *)anim

{

NSLog(@"开始了");

}

//动画结束时

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

//方法中的flag参数表明了动画是自然结束还是被打断,比如调用了removeAnimationForKey:方法或removeAnimationForKey方法,flag为NO,如果是正常结束,flag为YES。

NSLog(@"结束了");

}

其实比较重要的是有多个动画的时候如何在代理方法中区分不同的动画

两种方式

方式一:

如果我们添加动画的视图是全局变量,可使用该方法。

添加动画时,我们使用了

[self.imageView.layer addAnimation:animaGroup forKey:@"Animation"];

所以,可根据key来区分不同的动画

//动画开始时

- (void)animationDidStart:(CAAnimation *)anim

{

if ([anim isEqual:[self.imageView.layer animationForKey:@"Animation"]]) {

NSLog(@"动画组执行了");

}

}

方式二

添加动画的视图是局部变量时,可使用该方法

添加动画给动画设置key-value

[positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];

[transformAnima setValue:@"TransformAnima" forKey:@"AnimationKey"];

所以,可以根据key中不同的值来进行区分不同的动画

//动画结束时,没执行完一个动画,就会执行一次这个方法,因此可以通过判断valueForKey来判断是哪一个动画执行的

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"PositionAnima"]) {

NSLog(@"位置移动动画执行结束");

}

else if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"TransformAnima"]){

NSLog(@"旋转动画执行结束");

}

}

解决循环引用问题

由于CAAnimation的delegate使用的strong类型,所以在全局变量如下设置时会产生循环引用的情况

解决方案

  • 声明一个单独的类实现delegate的回调

//.h

#import <UIKit/UIKit.h>

@interface AnimationDelegate : NSObject

@end

//.m

#import "AnimationDelegate.h"

@implementation AnimationDelegate

- (void)animationDidStart:(CAAnimation *)anim

{

NSLog(@"Animation Start");

}

//

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

NSLog(@"Animation Stop");

}

- (void)dealloc

{

NSLog(@"Delegate Dealloc");

}

@end

使用方式

self.animation.delegate = [[AnimationDelegate alloc]init];

ACAKeyFrameAnimation使用总结

CABasicAnimation算是CAKeyFrameAnimation的 特殊情况,即不考虑中间变换过程,只考虑起始点与目标点就可以了。而CAKeyFrameAnimation则更复杂一些,允许我们在起点与终点间自定义 更多内容来达到我们的实际应用需求!

一,设定动画的属性和说明

values           属性指明整个动画过程中的关键帧点。需要注意的是,起点必须作为values的第一个值。

path 用于指定整个动画所经过的路径的。需要注意的是,当values与path同时指定 时,path会覆盖values,即values属性将被忽略。

keyTimes 用以指定每个子路径(AB,BC,CD)的时间。如果你没有显式地对keyTimes进行设置,则系统会默认每条子路径的时间 为:ti=duration/n。其中首尾必须分别是0和1。

timeFunctions 用以指定时间函数,类似于运动的加速度

calculationMode 决定了物体在每个子路径下是跳着走还是匀速走,跟timeFunctions属性有点类似

1)timeFunctions属性

kCAMediaTimingFunctionLinear//线性

kCAMediaTimingFunctionEaseIn//淡入

kCAMediaTimingFunctionEaseOut//淡出

kCAMediaTimingFunctionEaseInEaseOut//淡入淡出

kCAMediaTimingFunctionDefault//默认

2)calculationMode属性

const kCAAnimationLinear//线性,默认

const kCAAnimationDiscrete//离散,无中间过程,但keyTimes设置的时间依旧生效,物体跳跃地出现在各个关键帧上

const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效

const kCAAnimationCubic//平均,同上

const kCAAnimationCubicPaced//平均,同上

二,添加动画,(动画组执行是有顺序的)

CALayer  *rectLayer = [[CALayer alloc] init];

CAKeyframeAnimation *positionAnima = [CAKeyframeAnimation animationWithKeyPath:@"position"];

//设定关键帧位置,必须含起始与终止位置

positionAnima.values = @[[NSValue valueWithCGPoint:CGPointMake(15,15)],

[NSValue valueWithCGPoint:CGPointMake(320 - 15,15)],

[NSValue valueWithCGPoint:CGPointMake(320 - 15, 100)],

[NSValue valueWithCGPoint:CGPointMake(15,  100)],

[NSValue valueWithCGPoint:CGPointMake(15,15)]];

//设定每个关键帧的时长,如果没有显式地设置,则默认每个帧的时间=总duration/(values.count - 1)

positionAnima.keyTimes =  @[[NSNumber numberWithFloat:0.0],

[NSNumber numberWithFloat:0.6],

[NSNumber numberWithFloat:0.7],

[NSNumber numberWithFloat:0.8],

[NSNumber numberWithFloat:1]];

positionAnima.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];

positionAnima.repeatCount = 1000;

positionAnima.autoreverses = NO;

positionAnima.calculationMode = kCAAnimationLinear;

positionAnima.duration = 4;

[rectLayer addAnimation:rectRunAnimation forKey:@"QQQ"];

或者values 设置部分等效下面path设置

(这个是多条路径设置的)

CGMutablePathRef path = CGPathCreateMutable();

CGPathMoveToPoint(path, NULL, 15,  15);

CGPathAddLineToPoint(path, NULL, 320 - 15, 15);

CGPathAddLineToPoint(path, NULL, 320 - 15,100);

CGPathAddLineToPoint(path, NULL, 15,  100);

CGPathAddLineToPoint(path, NULL, 15, 15);

positionAnima.path = path;

CGPathRelease(path);

(单路径设置采用如下)

UIBezierPath *animPath = [[UIBezierPath alloc] init];

[animPath moveToPoint:starPoint];起点

[animPath addQuadCurveToPoint:endPoint controlPoint:ancholPoint];画线

暂停动画

-(void)pauseLayer:(CALayer*)layer

{

    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

    layer.speed = 0.0;

    layer.timeOffset = pausedTime;

}

开始动画

-(void)resumeLayer:(CALayer*)layer

{

    CFTimeInterval pausedTime = [layer timeOffset];

    layer.speed = 1.0;

    layer.timeOffset = 0.0;

    layer.beginTime = 0.0;

    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;

    layer.beginTime = timeSincePause;

}

时间: 2024-07-30 19:51:25

核心动画(CAKeyframeAnimation,CABasicAnimation)的相关文章

猫猫学IOS(三十九)UI之核心动画之CABasicAnimation(基础动画)

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一.CABasicAnimation简介 CAPropertyAnimation的子类 属性解析: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue 如

ios(CoreAnimation核心动画 ) CABasicAnimation动画与锚点

一.position和anchorPoint position:用来设置CALayer在父层中的位置,以父层的左上角为原点(0, 0) anchorPoint(锚点): 称为“定位点”.“锚点” 决定着CALayer身上的哪个点会在position属性所指的位置 以自己的左上角为原点(0, 0) 它的x.y取值范围都是0~1,默认值为(0.5, 0.5) 推荐一个连接:http://www.cnblogs.com/wendingding/p/3800736.html讲的非常详细,而且有图视,默认

coreAnimation核心动画(一)CABasicAnimation

2 1 // 2 // ViewController.m 3 // coreAnimation 4 // 5 // Created by ys on 15/11/21. 6 // Copyright (c) 2015年 ys. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 @property (nonatomic,strong)CALayer

核心动画(CAKeyframeAnimation)

Main.storyboard ViewController.m // //  ViewController.m //  8A02.核心动画 - CAKeyframeAnimation // //  Created by huan on 16/2/4. //  Copyright © 2016年 huanxi. All rights reserved. // #import "ViewController.h" @interface ViewController () @propert

核心动画与UIView

UIView与核心动画区别?(掌握) 1.核心动画只作用在layer. 2.核心动画看到的都是假像,它并没有去修改UIView的真实位置. 什么时候使用核心动画? 1.当不需要与用户进行交互,使用核心动画 2.当要根据路径做动画时,使用核心动画:CABasicAnimation,CAKeyFrameAnimation,两个都可以根据绘制的路径UIBizerPath来绘制路径来执行动画 3.当做转场动画时, 使用核心动画 (核心动画转场类型比较多)CATrasition或是UIView的核心动画

ios开发核心动画七:核心动画与UIView动画的区别

/** UIView与核心动画区别?(掌握) 1.核心动画只作用在layer. 2.核心动画看到的都是假像,它并没有去修改UIView的真实位置. 什么时候使用核心动画? 1.当不需要与用户进行交互,使用核心动画 2.当要根据路径做动画时,使用核心动画:CABasicAnimation,CAKeyFrameAnimation,两个都可以根据绘制的路径UIBizerPath来绘制路径来执行动画 3.当做转场动画时, 使用核心动画 (核心动画转场类型比较多)CATrasition或是UIView的核

iOS_40_核心动画

核心动画之CATransition转场动画 终于效果图: 核心动画之CAKeyFrameAnimation,图标抖动效果 终于效果图: 核心动画之CAAnimationGroup(动画组) 终于效果图: 核心动画之CAKeyFrameAnimationGroup(关键帧动画) 终于效果图: 核心动画之CABasicAnimation(基本动画) 终于效果图: UIView封装的动画,NSObject已经遵守了CAAnimationDelegate 终于效果图: 核心动画之幸运转盘 终于效果图:

猫猫学IOS(四十)UI之核心动画_抖动效果_CAKeyframeAnimation

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 效果: 效果一: 效果二: 代码: // // NYViewController.m // 图片抖动 // // Created by apple on 15-5-8. // Copyright (c) 2015年 znycat. All rights reserved. // #import "NYViewControlle

核心动画(关键帧动画)-转

一.简单介绍 是CAPropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值. 属性解析: values:就是上述的NSArray对象.里面的元素称为”关键帧”(keyframe).动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧. path:可以设置一

iOS开发——动画编程OC篇&amp;(二)核心动画

核心动画 一.简单介绍 CAPropertyAnimation的子类 属性解析: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue 如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态.但在实质上,图层的属性值还是动画