您的位置:首页 > 移动开发 > IOS开发

[IOS]CoreAnimation基础[翻译3部分]

2015-08-21 15:23 471 查看
让图层动起来
CA提供的组件能轻松的为你的app创建精美的动画效果。比如改变图层的大小,图层的位置,旋转,透明度等等。使用CA来初始化动画就像改变属性一样简单,就像你给属性赋值那样。
更多信息见

Advanced Animation Tricks.

让图层动起来仅仅只是改变图层的属性
你可以随你所愿的进行一些简单动画,无论是显示的还是隐示的。隐示的动画指的是用系统默认的动画效果来进行动画,然而显示的动画需要你自己来通过使用animation对象来配置。所以如果你不想写太多代码而仅仅使用一些简单的动画,所以就使用隐示的动画吧。
简单动画涉及到改变图层的某一属性从而让CA来在某一段时间端内产生动画。Layers定义了很多能影响图层视觉效果的属性。改变其中的任意一种属性就能产生动画。比如,将图层的透明度从1改变到0.产生了图层消散效果。
为了触发隐示的动画效果,你所需要做的只是更新图层对象的属性。当更改图层树中的对象时,你所进行的改变也就立即反应到对象。然而然后改变图层树中的对象视觉外观并不会立即改变。在这其中,CA将你进行的改变作为一个一个任务调度或者隐示动画来执行。因此,如果进行3-1的改变,CA将会创建动画对象,并且将其加入下一个更新循环。
Listing 3-1 Animating a change implicitly
theLayer.opacity = 0.0;


使用动画对象达到同样的效果,创建CABasicAnimaton对象然后配置动画参数。在将动画加进图层前,设置动画的起始和终结值,持续时间,或者其他的动画参数。3-2说明如何使用动画对象来实现消散效果。当创建动画对象,你指定想要使用动画的属性的key值(这里的key值就等于图层中的某个属性名),并为其设置参数。然后能够执行动画,只需要使用addAnimation:forKey方法加进图层即可。
Listing 3-2 Animating a change explicitly
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];

fadeAnim.fromValue = [NSNumber numberWithFloat:1.0];

fadeAnim.toValue = [NSNumber numberWithFloat:0.0];

fadeAnim.duration = 1.0;

[theLayer addAnimation:fadeAnim forKey:@"opacity"];

// Change the actual data value in the layer to the final value.

theLayer.opacity = 0.0;


不像隐示动画那样只需要更新图层对象的值就能产生动画,显示动画并不更改图层树中的数据。显示动画仅仅产生动画,在动画的结束, CA移除图层中的动画对象,然后根据当前值重新绘制。如果你想动画的效果在之后有效,那么久必须像上面最后一行那样更新属性的值。

无论显示还是隐示动画,都在当前运行循环结束之后执行,并且在当前线程必须为动画提供运行循环来执行。如果同时改变了多种属性,或者添加多个动画对象到图层,这些属性的改变也是同时的。比如,你可以通过设置动画来达到让图层消散的移除屏幕外。更多信息,见
Customizing the Timing of an Animation

使用关键帧(keyframe)动画来改变图层的属性
基于属性的动画将图层的某个值从起始值改变成结束值,CAKeyframeAnimation对象,让你的动画经过一系列的值,来达到线性或者非线性的效果。关键帧动画由一系列目标值和时间定位的集合组成。在最简单的配置中,你使用数组来指定值和时间。为了改变图层的位置属性,你可以让这些改变遵循某一路径。然后动画对象从关键帧里面提取出动画,然后逐步从一个值变到另外一个值在给定的时间周期里。
图3-1显示了一个5秒图层位置属性变更动画。这里仅给出链接可以看一下。指定路径需要用到CGPathRef数据理性。代码如3-3
动画链接



Listing 3-3 Creating a bounce keyframe animation
// 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.

theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];

theAnimation.path=thePath;

theAnimation.duration=5.0;

// Add the animation to the layer.

[theLayer addAnimation:theAnimation forKey:@"position"];


指定关键帧的值
关键帧的值时关键帧动画的核心。这些值定义了动画一段时间内的动画行为。指定关键帧值的主要方法就是包含CGPoint类型,也可以指定CGPathRef。
当指定数组的值,你所放进数组的数据依据属性所需要。你可以直接直接在数组中添加对象,然而一些对象必须转换成id类型才能被加入,并且所有值都必须封装成对象。比如:
1.对于需要CGRect类型的属性,将其封装成NSValue对象
2.对于图层的缩放转换属性,封装成CATransform3D矩阵成NAValue对象。该属性产生的关键帧动画,会用矩阵进行转换依次。
3.对于borderColor属性,在添加进数组前转换CGColorRef数据类型成id类型。
4.对于CGFloat类型的,封装成NSNumber然后添加进数组。
5.当对图层的contents属性进行动画时,指定一组CGImageRef数据类型。
对于需要CGPoint数据类型的属性,可以创建包含多点的数组或者使用CGPathRef。当以多点的数组的形式指定值的时,关键帧动画会在连续的两点间画直线,然后在动画执行时沿着这些直线。当指定CGPathRef类型为值的时,动画会根据实际的路径进行,比如例3-3那样。

指定关键帧动画的定时
对于关键帧的定时和行进速度比基本动画要复杂的多,并且有多个属性你需要控制。
1.calculationMode属性,定义了计算动画时间定位的算法,该属性值影响了其他定时相关的属性。
1.线性或者二次方动画—即calculationMode属性设置为kCAAnimationLinear或者kCAAnimationCubic.该模式将给予你对动画定时的最大掌控。
2.行进动画—即calculationMode设置为kCCAAnimationPaced或者kCAAnimationCubicPaced,并不依赖由外部提供的keyTimes和timingFunctions属性,动画以常量速度进行。
3.离散动画—即calculationMode设置为kCAAnimationDiscrete,将会使动画并非连续的,将会使动画只进行关键帧。该模式使用keyTimes属性,但是忽略timingFunction属性。
2.keyTimes属性制定了关键帧值的时间标记,该属性只能在caculationMode属性设置为kCAAnimationLiner,kCAAnimationDiscrete,或者kCAAnimationCubic的时候设置。并不能用于行进动画。
3.timingFunctions属性制定了每一帧片段的时间标记曲线。
如果你想要自己处理动画定时,使用kCAAnimationLiner和kCAAnimationCubic模式和keyTimes和timingFunctions属性。

在动画进行时停下来
动画通畅会在运行结束才停下来,但是你可以在执行的时候停下他们,使用以下两种技术。
1.从图层的移除某一动画对象,调用图层的removeAnimationForKey:方法来移除对象。该方法移除你所用addAnimation:forKey添加进图层key的对象。key值不能为nil。
2.移除图层中所有动画对象,调用removeAllAnimations方法,这个方法移除所有正在进行的动画。然后更具当前状态重绘图层。
当你从图层中移除动画时,CA会更具当前值重新绘制图层对象。因为当前值通常是动画结束时的值,所以,这将会导致图层的外观跳跃的改变。如果你保持图层在动画进行中的最后一帧的值,那么久从presentationTree中取回该值,然后再设置到图层树。

同时动画的改变多个值
如果你想要同时将多个动画添加进图层,你可以使用CAAnimationGroup将它们编组。使用组对象简化了多个对象的管理,并且提供了一个统一的配置点。定时和持续时间值,都可以通过设置组的属性来重写。
3-4告诉你如何使用组动画,同时进行两边相关的动画在同一时间段
Listing 3-4 Animating two animations together
// Animation 1

CAKeyframeAnimation* widthAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];

NSArray* widthValues = [NSArray arrayWithObjects:@1.0, @10.0, @5.0, @30.0, @0.5, @15.0, @2.0, @50.0, @0.0, nil];

widthAnim.values = widthValues;

widthAnim.calculationMode = kCAAnimationPaced;

// Animation 2

CAKeyframeAnimation* colorAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];

NSArray* colorValues = [NSArray arrayWithObjects:(id)[UIColor greenColor].CGColor,

(id)[UIColor redColor].CGColor, (id)[UIColor blueColor].CGColor,  nil];

colorAnim.values = colorValues;

colorAnim.calculationMode = kCAAnimationPaced;

// Animation group

CAAnimationGroup* group = [CAAnimationGroup animation];

group.animations = [NSArray arrayWithObjects:colorAnim, widthAnim, nil];

group.duration = 5.0;

[myLayer addAnimation:group forKey:@"BorderChanges"];


更先进的将动画组织在一起就是使用transaction对象,Transaction提供了更灵活的方式让你创建动画,并且能够单独的为每一个动画赋值。更多信息见
Explicit Transactions Let You Change
Animation Parameters

检测动画的结束
CA提供检测动画起始和结束。该通知出现的时候就是一个好时机来进行清理一些与动画相关的任务。比如,你可能使用一个起始通知来设置某些相关状态,然后在结束时清理掉这些状态。
两种方式来得到动画的状态通知
1.使用完成快哉当前的transaction上,使用setCompletionBlock方法,当在transaction中的对像完成时就会执行该块。
2.设置CAAnimation对象的委托delegate没,然后实现其animationDidStart和animationDidStop委托方法。
如果你想要链接两个动画,以达到一个结束了然后另外一个开始效果,不要使用动画的animation通知。应该使用beginTime属性在来设置你动画的理想的开始时间。更多信息见

Customizing the Timing of an Animation.

如何给基于图层支持视图添加动画
如果一个图层属于基于图层支持的视图,那么推荐添加的动画的方法是使用UIKit提供的接口去添加动画。同时也可以直接使用CA创建图层动画。具体实现依赖于平台。

IOS上修改图层规则
IOS上因为视图之下总是有图层,UIView本身就从视图对象会的其本身的大多数数据。所以,改变图层的结果也就自动的反馈的改变了视图对象。这个特性意味着你可以使用CA或者UIView来改变界面。
如果你想要CA类类初始动画,你必须在在基于视图的动画块内进行CA的所有调用。UIView类默认禁止图层动画,但是可以在动画块内重新使用。所以任何在动画块外的动画都是不响应的。如3-5的例子,如何改变视隐示的改变图层的属性。在该例中,myNewPosition变量在块内被计算和捕获。两个动画是同事进行的,但是透明度的动画效果改变使用了默认持续时间,而位置改变的动画效果指定了值。
Listing 3-5 Animating a layer attached to an iOS view
[UIView animateWithDuration:1.0 animations:^{

// Change the opacity implicitly.

myView.layer.opacity = 0.0;

// Change the position explicitly.

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

theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];

theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];

theAnim.duration = 3.0;

[myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];

}];


记得更新视图的Constraints
如果你使用基于constraints的布局来管理视图的位置,你必须这些constraints妨碍到动画。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: