动画层内容

来源:互联网 发布:矩阵防御 编辑:程序博客网 时间:2024/05/17 06:45
动画层内容:
  通过扩展这些拥有层的视图,由核心动画提供的基础类使给你的app的层创建精准的动画变得简单。举例包括改变层的frame rectangel,屏幕位置,使用旋转,改变它的透明度。使用核心动画,创建一个动画经常像改变一下这些属性一样简单,但是,你仍然需要创建动画,并明确的设置动画参数   了解更多的关于创建更为先进动画的信息,看Advanced Animation Tricks

改变层属性的动画栗子:
   根据你的需要, 你可以实现一些简单的动画 含蓄的或者明确的 。含蓄的动画使用默认的timing和动画属性改完成实施一个动画,然而明确的动画需要配置你自己使用的动画对象的属性。所以含蓄的动画的非常适合这样的情形(你想做一些改变,又不想写很多代码,而且默认的timing已经非常适合你了)
   简单的动画包括改变层的属性,让core Animation通过时间 animate这些改变,。 Layers定义了很多能影响层可见外观的属性。 改变这些属性的一个就是animate 外观改变的方式。例如:改变层的透明度 从1.0到0.0来使层淡出,变为透明。
重要:虽然你可以能直接使用core animation 接口 动画 layer-backed views ,但是你需要做些额外的操作。了解更多的关于如何使 结合 layer-backed views, 看how to animate layer-Backed Views

触发一个动画,你所要多的就是更新层对象的属性。但你修改层树上的层对象时, 你的修改会被这些对象立即响应。然而,这些层对象可见的外观不会立即被改变。而发生了什么呢,是核心动画使用这些改变作为一个触发来创建和计划一个或更多的含蓄隐式动画来执行。如此,做一个改变像list 3-1这样引起核心动画来为你创建一个动画对象,并且计划动画run 在一个更新cycle。

Listing 3-1  Animating a change implicitly

theLayer.opacity = 0.0;

用一个动画对象来显式的实现一些改变,创建一个CABasicAnimation对象并且使用它来配置一些动画参数。在你给层添加动画之前,你为动画可以设置开始和结束的值,改变duration,或者改变任何一个其他的动画参数。Listing 3-2 展示如何使用动画对象淡出一个层。当你创建对象的时候,你指定一个关键路径给你动画的属性,然后设置一些动画参数。为了执行动画,你要使用addAnimation:forKey:方法来把他添加到你想animate的动画上。
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;  

提示:当你创建一个显式的动画时,记得,赋值给fromValue属性。如果你没有赋值的话,core animation用层当前的值作为开始值。如果你已经更新了属性为最终的值,可能不会产生你想要的结果。

不想隐式动画,你更新层对象的数组值,一个明显的,显式的动画不会更改层数的数据。显式的动画只会制造动画效果。在动画结束之后,核心动画从层上移除动画对象并且重新绘制层用当前的数据值。当你想改变一个显式的动画的改变变为永久的,你必须像先前的例子一样最终一定要更新一下层属性的值。
明显的动画和含蓄的动画通常在当前的run loop cycle结束之后开始执行,并且当前线程必须有一个为了动画执行的run loop 。如果你想改变多重属性,或者你添加多重动画对象给层。所有的这些属性改变,必须同时animate。如果,你可以淡出一个层同时把它移出屏幕(通过配置同时动画在同一个时候)。然和,你也可以配置动画对象来在一个特定的时间开始。了解更过关于修改动画timing,看

Customizing the Timing of an Animation.


使用关键帧动画来改变层属性
然后一个基于属性的动画改变一个属性从一个开始值到结束值,一个CAKeyframeAnimation对象,让你用这样的方式, 可以是线性的,也可不是线性的方式,通过一系列的目标值来animate。一个关键帧动画由一系列的目标数据值和每个值需要达到的次数组成。在一个最简单的配置里面,你同时指定值和次数用一个数组。对于一个层位置的变化,你可以follow a path 实现这些变化。该动画对象用这些你指定的关键帧来建立一个动画,通过插入一个值给下一个在给定的时间区域内。

Figure 3-1展示了一个5s层位置的动画。位置动画follow一个Path可以通过CGPathCF数据类型指定。 The core for this animation is shown in Listing 3-3



5 second keyframe animation of a layer’s position property

Listing 3-3 shows the code used to implement the animation in Figure 3-1. The path object in this example is used to define the position of the layer for each frame of the animation.

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数据类型来替代。
When specifying an array of values, what you put into the array depends on the data type required by the property. You can add some objects to an
当你指定一组值的时候,你想要放进的数组的东西依赖于属性的数据类型。你可以直接加到数组里;然而,一些对象在加入之前,必须转成id形式,并且 所有的纯量的数据类型或结构体必须包到一个对象里面。例如:

For properties that take a CGRect (such as the bounds and frame properties), wrap each rectangle in an NSValue object.
对于带有CGRect的属性,包裹每一个长方形在一个NSValue对象中
  • For the layer’s transform property, wrap each CATransform3D matrix in an NSValue object. Animating this property causes the keyframe animation to apply each transform matrix to the layer in turn.
  • 对于一个层的transform属性,包裹每一个CATransform3D矩阵在一个NSValue对象里面  。动画这个属性使关键帧动画应用到每一个transform matrix
  • For the borderColor property, cast each CGColorRef data type to the type id before adding it to the array.
对于borderColor属性, 在加入到数组之前转换每一个CGColorRef数据类型为id类型
  • For properties that take a CGFloat value, wrap each value in an NSNumber object before adding it to the array.
对于带有CGFloat值得属性,在加入数组之前包裹每一个值到NSNumber对象中
  • When animating the layer’s contents property, specify an array of CGImageRef data types.
  • 当动画一个层的contents属性的时候, 赋值一个 CGImageRef数据类型的数组。
For properties that take a CGPoint data type, you can create an array of points (wrapped in NSValue objects) or you can use a
对于这些带有CGPoint属性,你可以创建数组存放包裹在NSValue对象中的points,或者是用CGPathRef对象来赋值一个fllow的路径。
CGPathRef object to specify the path to follow. When you specify an array of points, the keyframe animation object draws a
当你赋值一个points的数组,关键帧动画在连续的点之间画一条线,并且follows 这个path。 当你赋值一个 CGPathRef对象的时候,动画
straight line between each successive point and follows that path. When you specify a CGPathRef object, the animation starts
启动在路径开始的点,并且follow 这个轮廓, 包括伴随的任何曲线。你可以使用任何打开和闭合的路径。
at the beginning point of the path and follows its outline, including along any curved surfaces. You can use either an open or closed path.

Specifying the Timing of a Keyframe Animation
指定一个关键帧动画的Timing
The timing and pacing of keyframe animations is more complex than those of basic animations and there are several properties you can use to control it:
关键帧的时间和速度比基础动画复杂,你可以通过下面这些属性控制他们。
  • The calculationMode property defines the algorithm to use in calculating the animation timing. The value of this property affects how the other timing-related properties are used.
  • calculationMode属性定义了用来计算动画时间的算法。这个属性的值影响其他时间相关属性的使用

    • Linear and cubic animations—that is, animations where the calculationMode property is set to kCAAnimationLinear or kCAAnimationCubic—use the provided timing information to generate the animation. These modes give you the maximum control over the animation timing.
    • 线性的和立方形动画 - 就是, calculationMode属性被设置为KCAnimationLinear或者KCAAnimationCubic—用提供时间信息来生成动画。这些方法给你最大的控制,通过动画timing
    • Paced animations—that is, animations where the calculationMode property is set to kCAAnimationPaced or kCAAnimationCubicPaced—do not rely on the external timing values provided by the keyTimes or timingFunctions properties. Instead, timing values are calculated implicitly to provide the animation with a constant velocity.
  • 节奏动画—就是,属性本设置为KCAAnimationPaced或者KCAAnimationCubicPaced的动画 — 不依赖通过KeyTimes或者timingFunctions属性提供的外在的timing Values.相反, timing values 被隐式的计算来,提供给动画固定的速度。

    • Discrete animations—that is, animations where the calculationMode property is set to kCAAnimationDiscrete—cause the animated property to jump from one keyframe value to the next without any interpolation. This calculation mode uses the values in the keyTimes property but ignores the timingFunctions property
    • 分离动画—就是, caculationModel被设置为KCAAnimationDiscrete属性的动画— 引起动画属性 从一个帧调到下一帧不带任何的插入。
    • 这种计算模式用keyTimes属性提供的值但是忽略timingFunction属性
  • The keyTimes property specifies time markers at which to apply each keyframe value. This property is used only if the calculation mode is set to kCAAnimationLinear,kCAAnimationDiscrete, or kCAAnimationCubic. It is not used for paced animations.

  • The timingFunctions property specifies the timing curves to use for each keyframe segment. (This property replaces the inherited timingFunction property.)
timingFunctions属性赋值一个timing 曲线 来为每一个帧段使用。(这个属性替代继承timingFunction属性)

If you want to handle the animation timing yourself, use the kCAAnimationLinear or kCAAnimationCubic mode and the keyTimes and timingFunctions properties. The keyTimes defines the points in time at which to apply each keyframe value. The timing for all intermediate values is controlled by the timing functions, which allow you to apply ease-in or ease-out curves to each segment. If you do not specify any timing functions, the timing is linear.
如果你想自己处理动画timing, 使用 KCAAnimationLinear 或者 KCAAnimationCubic 模式和 keyTimes和timingFunctions属性。key times属性定义了应用到每一帧值的点。所有中间值de timing被 the timing functions控制, 它允许你应用 ease- in 或者 ease out 曲线到每一个segment。 如果你没有指定任何timing functions, the timing就是linear

Stopping an Explicit Animation While It Is Running
暂停一个正在运行的 explicit animation。
Animations normally run until they are complete, but you can stop them early if needed using one of the following techniques:
动画正常运行知道动画结束,但是你可以提前结束动画如果你需要的话, 用下面的技术可以做到。

  • To remove a single animation object from the layer, call the layer’s removeAnimationForKey: method to remove your animation object. This method uses the key that was passed to theaddAnimation:forKey: method to identify the animation. The key you specify must not be nil.
为了从层移除一个单独的单独的动画对象, 调用 removeAnimationForkey方法移除你的动画对象。这个方法使用的key值,是之前被passed的 用addAnimation:forked方法来区分动画的。 这个key不能为空。
  • To remove all animation objects from the layer, call the layer’s removeAllAnimations method. This method removes all ongoing animations immediately and redraws the layer using its current state information.
为了从你的层上移除所有动画, 调用层的 removeAllAnimations方法。 这个方法立即移除所有ongoing动画,并且redraw 层用当前的状态信息。
Note: You cannot remove implicit animations from a layer directly. 你不能直接从层上移除implicit 动画

When you remove an animation from a layer, Core Animation responds by redrawing the layer using its current values. Because the current values are usually the end values of the animation, this can cause the appearance of the layer to jump suddenly. If you want the layer’s appearance to remain where it was on the last frame of the animation, you can use the objects in the presentation tree to retrieve those final values and set them on the objects in the layer tree.

当你从层上移除动画的时候, core Animation 响应 redrawing层方法用当前的状态值。因为当前的状态值通常是动画的结束值,这个可以引起当前层外观跳帧。如果你想层的外观保持动画的最后一帧的样子,你可用presentation树上的对象来回复这些最终的值并且设置他们到层树上的对象。
For information about pausing an animation temporarily, see Listing 5-4.
更多的信息关于立刻暂停动画的。看 Listing 5-4.

Animating Multiple Changes Together
同时动画多个changes 
If you want to apply multiple animations to a layer object simultaneously, you can group them together using a CAAnimationGroup object. Using a group object simplifies the management of multiple animation objects by providing a single configuration point. Timing and duration values applied to the group override those same values in the individual animation objects.
如果你想同时的应用多样的动画到一个层对象, 你可以group他们一起 用 CAAnimationGroup对象。 用一个组对象简明的管理多种动画对象。Timing 和duration值应用到组是相同的值在每一个独立的动画对象上
Listing 3-4 shows how you would use an animation group to perform two border-related animations at the same time and with the same duration.
listing 3-4 展示了你可以使用动画组对象来实现两个boder相关的动画 使用相同的time 和同样的duration。

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"];
A more advanced way to group animations together is to use a transaction object. Transactions provide more flexibility by allowing you to create nested sets of animations and assign different animation parameters for each. For information about how to use transaction objects, see Explicit Transactions Let You Change Animation Parameters.
一个更多先进的way 来group动画是用transaction对象。transactions提供更过的柔韧性允许你使用一堆动画,独立的给不同的动画设置。
对于更多的使用transaction对象, 用 explicit transactions let you change animation parameters.

Detecting the End of an Animation
观察动画的结束。
Core Animation provides support for detecting when an animation begins or ends. These notifications are a good time to do any housekeeping tasks associated with the animation. For example, you might use a start notification to set up some related state information and use the corresponding end notification to tear down that state.
core Animation 提供 观察动画的开始和结束的支持。这些通知是非常好的time 来做任何和动画相关的houseKeeping任务。例如,你可以使用一个start notification 来设置一些相关的状态信息,和使用相关的结束通知来 tear down that state。

There are two different ways to be notified about the state of an animation:
这用两种不同的方式来通知一个动画的状态。
  • Add a completion block to the current transaction using the setCompletionBlock: method. When all of the animations in the transaction finish, the transaction executes your completion block.
添加一个完成回调给当前的transaction 用setCompletionBlock方法。当所有的动画在transaction结束时,这个transaction处理你completion block.
  • Assign a delegate to your CAAnimation object and implement the animationDidStart: and animationDidStop:finished: delegate methods.
复制给一个CAAnimation对象的代理来完成 animationDidStart 和 animationDidStop:finished 代理方法。
If you want to chain two animations together so that one starts when the other finishes, do not use animation notifications. Instead, use the beginTime property of your animation objects to start each one at the desired time. To chain two animations together, set the start time of the second animation to the end time of the first animation. For more information about animation and timing values, see Customizing the Timing of an Animation.
如果你想链接个动画一起 so that 一个开始在其他结束时, 不能用动画通知。相反,你用动画对象的beginTime属性来开始每一个动画在其他的时间点。把两个动画连接起来,设置第二个动画的开始时间来决定第一个动画的结束。对于更多的信息关于动画和timimg值,看Customizing the Timing of an Animation.

How to Animate Layer-Backed Views
如何animate layer-backed views
If a layer belongs to a layer-backed view, the recommended way to create animations is to use the view-based animation interfaces provided by UIKit or AppKit. There are ways to animate the layer directly using Core Animation interfaces but how you create those animations depends on the target platform.
如果 一个层是属于 a layer-backed View,推荐的创建动画的方式是用 the view-based 动画接口通过UIkit 或者是AppKit。这些来动画层的方式直接使用Core Animation接口但是如何创建动画依赖于目标平台。

Rules for Modifying Layers in iOS
在iOS上修改layer的规则
Because iOS views always have an underlying layer, the UIView class itself derives most of its data from the layer object
因为iOS view 经常有在一个在其之下的层, UIView类自己直接从层对象获取大多数他的数据。所以,你对层多的改变会自动的反应到view对象上。这个行为意味着你既可以用核心动画,也可以欧尼UIView接口来做一些changes。
directly. As a result, changes you make to the layer are automatically reflected by the view object as well. This behavior means that you can use either the Core Animation or UIView interfaces to make your changes.

If you want to use Core Animation classes to initiate animations, you must issue all of your Core Animation calls from inside a view-based animation block. The UIView class disables layer animations by default but reenables them inside animation blocks. So any changes you make outside of an animation block are not animated. Listing 3-5 shows an example of how to change a layer’s opacity implicitly and its position explicitly. In this example, the myNewPosition variable is calculated beforehand and captured by the block. Both animations start at the same time but the opacity animation runs with the default timing while the position animation runs with the timing specified in its animation object.
如果你想使用core Animation类初始化对象,你必须issue所有你的Core Animation调用 inside a view-base animation block.视图类默认是不能动画的,但是在block里可以使用层动画。所以你想做的任何改变在动画block里面是不能动画的。Listing 3-5 展示了如何隐式的改变层的透明度 和显式的改变它的位置。在这个例子中, myNewPosition 变量是提前计算好的,并且被blockcaptured。两个动画同时开始,但是透明度动画用默认的timing然和位置动画运行时用动画对象指定的timing

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"];
}];

Rules for Modifying Layers in OS X

To animate changes to a layer-backed view in OS X, it is best to use the interfaces of the view itself. You should rarely, if ever, directly modify the layer that is attached to one of your layer-backed NSView objects. AppKit is responsible for creating and configuring those layer objects and for managing them while your app is running. Modifying the layer could cause it to get out of sync with the view object and could lead to unexpected results. For layer-backed views, your code must absolutely not modify any the following properties of the layer object:

  • anchorPoint

  • bounds

  • compositingFilter

  • filters

  • frame

  • geometryFlipped

  • hidden

  • position

  • shadowColor

  • shadowOffset

  • shadowOpacity

  • shadowRadius

  • transform

Important: The preceding restrictions do not apply to layer-hosting views. If you created the layer object and associated it with a view manually, you are responsible for modifying the properties of that layer and keeping the corresponding view object in sync.

AppKit disables implicit animations for its layer-backed views by default. The view’s animator proxy object reenables implicit animations automatically for you. If you want to animate layer properties directly, you can also programmatically reenable implicit animations by changing the allowsImplicitAnimation property of the current NSAnimationContext object to YES. Again, you should do this only for animatable properties that are not in the preceding list.

Remember to Update View Constraints as Part of Your Animation

If you are using constraint-based layout rules to manage the position of your views, you must remove any constraints that might interfere with an animation as part of configuring that animation. Constraints affect any changes you make to the position or size of a view. They also affect the relationships between the view and its child views. If you are animating changes to any of those items, you can remove the constraints, make the change, and then apply whatever new constraints are needed.

For more information on constraints and how you use them to manage the layout of your views, see Auto Layout Guide.

如果是用auto layout 小心哦,最好动画之前,先删掉约束 
0 0
原创粉丝点击