基于属性的动画是指在动画执行过程中随时间改变的是layer层的一些单一属性,比如position、background color以及bounds等。本文主要阐述的是核心动画的抽象属性动画以及为layer属性所提供的基本的以及关键帧动画。
Property-Based Abstraction
CAPropertyAnimation是CAAnimation的一个为layer的某个属性提供特定动画的一个子类。基于属性的动画支持那些能够被数学插入属性值的一些熟悉的动画效果,包括:
- 整数和小数
- CGRect, CGPoint, CGSize和CGAffineTransform结构体
- CATransform3D结构体
- CGColor以及CGImage
像所有的动画一样,属性动画必须要是某一个特定layer的动画。这个需要被执行动画的layer属性是通过key-value键值对的方式来访问。例如,需要对一个layer的x坐标执行动画,需要通过key path“position.x”来定义一个动画,并且将这个动画赋值给这个layer。
你不需要直接创建一个CAPropertyAnimation对象实例,而是需要创建一个CABasicAnimation或者CAKeyframeAnimation的实例对象。
Basic Animations
CABasicAnimation动画类为layer属性提供了基本的、单关键帧动画,可以构建一个CABasicAnimation实例对象,并通过* animationWithKeyPath:方法来定义layer所需要执行动画的属性。
图1表示的是layer的position属性从 (74.0,74.0)到(566.0,406.0),并且父层的bounds属性为 (0.0,0.0,640.0,480.0)*。
配置基础动画的插入值
通过CABasicAnimation的fromValue、* byValue、toValue属性来确定被插入的值。虽然都是可选项,但是至少有两个值应该是非空的,也就是(non-nil*)的。
这几个属性的使用方法通常有以下几种:
- fromValue以及toValue都是非空的,那么插入的值就是介于这两者之间的。
- fromValue以及byValue是非空的,那么插入的值就是介于fromValue以及(fromValue+byValue)之间的。
- byValue和toValue是非空的,那么插入的值就介于(toValue-byValue)以及toValue之间的。
- fromValue是非空的,那么插入的值就介于fromValue和当前值的中间。
- toValue是非空的,那么插入的值就在keyPath的当前值和toValue之间
- byValue非空,随时间变化的值在keyPath对应的当前值以及该值加上byValue之后的值中间
- 所有的属性都nil
基础动画的例子
该段代码能够实现和图1一样的效果
CABasicAnimation *theAnimation;
// create the animation object, specifying the position property as the key path
// the key path is relative to the target animation object (in this case a CALayer)
theAnimation=[CABasicAnimation animationWithKeyPath:@"position"];
// set the fromValue and toValue to the appropriate points
theAnimation.fromValue=[NSValue valueWithPoint:NSMakePoint(74.0,74.0)];
theAnimation.toValue=[NSValue valueWithPoint:NSMakePoint(566.0,406.0)];
// set the duration to 3.0 seconds
theAnimation.duration=3.0;
// set a custom timing function
theAnimation.timingFunction=[CAMediaTimingFunction functionWithControlPoints:0.25f :0.1f :0.25f :1.0f];
关键帧动画——Keyframe Animations
CAKeyframeAnimation与基础动画相似,支持关键帧动画。但是,它是可以为执行动画的目标对象的某个属性设置一组数值来表述该属性值随动画进行的变化。
图2 表述了一个layer的position属性的使用CGPathRef的5秒钟的关键帧动画
关键帧动画的值
关键帧动画通常是以以下两种方式来使用:通过path(Core Graphics path)属性或者是一组Values属性
Core Graphics通常用来执行layer层的anchorPoint或者position动画,也就是说,执行的是CGPoints属性动画。路径中的每一个点都定义了确定关键帧动画的一部分以及插入的点(除了moveto点),但是如果拥有了一个确定的path路径的话,那么这个values属性值就会被忽略。
默认情况下,layer会按照设定的旋转方式进行旋转执行,设定旋转方式rotationMode为* kCAAnimationRotateAuto或者 kCAAnimationRotateAutoReverse会使layer依照路径轨迹进行旋转。
提供一系列的values*属性值供layer的不同类型属性执行动画。例如:
- 一组CGImage对象并且设置动画的关键路径为layer的content属性,将会使layer按照给定的图片执行动画。
- 一组CGRects对象并且设置动画关键路径为layer的frame属性,会使layer的内容在给定的矩形范围内重复执行。
- 一组CATransform3D矩阵,并且设定动画关键路径为transform属性。
Keyframe Timing and Pacing Extensions
关键帧动画要比基本动画拥有更加复杂的时间以及执行节奏模型。
忽略继承的timingFunction属性,可以传一组数值给CAMediaTimingFunction。每个时间函数都描述了关键帧随动画执行的变化。
虽然CAKeyframeAnimation拥有duration属性,但是可以通过keyTimes属性来细微的调整动画的执行时机。
keyTimes属性定义了动画执行范围内关键帧的一系列NSNumber对象。每个值都是介于0.0~1.0之间的。所有keyTimes元素定义了关键帧的值在整个动画持续时间内百分比。每一个元素都不能比之前的元素小。
keyTimes的值基于calculationMode属性的值:
- 如果calculationMode设置为kCAAnimationLinear,那么第一个和最后一个元素必须分别为0.0和1.0。
- 如果calculationMode设置为kCAAnimationDiscrete,那么第一个元素必须是0.0
- 如果calculationMode设置为kCAAnimationPaced,那么keyTimes属性的值就没有作用了。
关键帧动画例子
下面的这段代码会形成和图2一样的动画效果。
// create a CGPath that implements two arcs (a bounce)
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,74.0,74.0);
CGPathAddCurveToPoint(thePath,NULL,74.0,500.0,
320.0,500.0,
320.0,74.0);
CGPathAddCurveToPoint(thePath,NULL,320.0,500.0,
566.0,500.0,
566.0,74.0);
CAKeyframeAnimation * theAnimation;
// create the animation object, specifying the position property as the key path
// the key path is relative to the target animation object (in this case a CALayer)
theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
theAnimation.path=thePath;
// set the duration to 5.0 seconds
theAnimation.duration=5.0;
// release the path
CFRelease(thePath);