Core Animation

Transaction Management Classes

Every modification to an animatable property of a layer must be part of a transaction. CATransaction is the Core Animation class responsible for batching multiple animation operations into atomic updates to the display. Nested transactions are supported.

Core Animation supports two types of transactions: implicit transactions and explicit transactions. Implicit transactions are created automatically when an animatable property of a layer is modified by a thread without an active transaction and are committed automatically when the thread's run-loop next iterates. Explicit transactions occur when the application sends theCATransaction class a begin message before modifying the layer, and a commit message afterwards.

Providing CALayer Content

You specify the content of a CALayer instance in one of the following ways:

  • Explicitly set the contents property of a layer instance using a CGImageRef that contains the content image.

  • Specify a delegate that provides, or draws, the content.

  • Subclass CALayer and override one of the display methods.

Setting the Contents Property

A layer’s content image is specified by the contents property to a CGImageRef. This can be done from another object when the layer is created (as shown in Table 3) or at any other time.

Listing 1  Setting a layer’s contents property

CALayer *theLayer;
 
// create the layer and set the bounds and position
theLayer=[CALayer layer];
theLayer.position=CGPointMake(50.0f,50.0f);
theLayer.bounds=CGRectMake(0.0f,0.0f,100.0f,100.0f);
 
// set the contents property to a CGImageRef
// specified by theImage (loaded elsewhere)
theLayer.contents=theImage;

Using a Delegate to Provide Content

You can draw content for your layer, or better encapsulate setting the layer’s content image by creating a delegate class that implements one of the following methods: displayLayer: or drawLayer:inContext:.

Implementing a delegate method to draw the content does not automatically cause the layer to draw using that implementation. Instead, you must explicitly tell a layer instance to re-cache the content, either by sending it a setNeedsDisplay  or  setNeedsDisplayInRect:  message, or by setting its  needsDisplayOnBoundsChange  property to  YES .

Providing CALayer Content by Subclassing

CALayer subclasses can draw the layer’s content into a graphics context by overriding drawInContext:

Subclassing CALayer and implementing one of the drawing methods does not automatically cause drawing to occur. You must explicitly cause the instance to re-cache the content, either by sending it a setNeedsDisplay orsetNeedsDisplayInRect: message, or by setting its needsDisplayOnBoundsChange property to YES.

Positioning constants for a layer’s contentsGravity property

Position constant

Description

kCAGravityTopLeft

Positions the content image in the top left corner of the layer.

kCAGravityTop

Positions the content image horizontally centered along the top edge of the layer.

kCAGravityTopRight

Positions the content image in the top right corner of the layer.

kCAGravityLeft

Positions the content image vertically centered on the left edge of the layer.

kCAGravityCenter

Positions the content image at the center of the layer.

kCAGravityRight

Positions the content image vertically centered on the right edge of the layer.

kCAGravityBottomLeft

Positions the content image in the bottom left corner of the layer.

kCAGravityBottom

Positions the content image centered along the bottom edge of the layer.

kCAGravityBottomRight

Positions the content image in the top right corner of the layer.

 Scaling Constants For A Layer’s contentsGravity Property

Scaling constant

Description

kCAGravityResize

Resize the content image to completely fill the layer bounds, potentially ignoring the natural aspect of the content. This is the default.

kCAGravityResizeAspect

Resize the content image to scale such that it is displayed as large as possible within the layer bounds, yet still retains its natural aspect.

kCAGravityResizeAspectFill

Resize the content image to scale such that it is displayed filling the layer bounds, yet retaining its natural aspect. This may cause the content to extend outside the layer bounds.

 The animation occurs automatically in a separate thread, without further interaction with your application.

Core Animation provides an expressive set of animation classes you can use in your application:

  • CABasicAnimation provides simple interpolation between values for a layer property.

  • CAKeyframeAnimation provides support for key frame animation. You specify the key path of the layer property to be animated, an array of values that represent the value at each stage of the animation, as well as arrays of key frame times and timing functions. As the animation runs, each value is set in turn using the specified interpolation.

  • CATransition provides a transition effect that affects the entire layer's content. It fades, pushes, or reveals layer content when animating. The stock transition effects can be extended by providing your own custom Core Image filters.

  • CAAnimationGroup allows an array of animation objects to be grouped together and run concurrently.


Implicit Animation

Core Animation’s implicit animation model assumes that all changes to animatable layer properties should be gradual and asynchronous. Dynamically animated scenes can be achieved without ever explicitly animating layers. Changing the value of an animatable layer property causes the layer to implicitly animate the change from the old value to the new value. While an animation is in-flight, setting a new target value causes the animation transition to the new target value from its current state.

 Implicitly animating a layer’s position property

// assume that the layer is current positioned at (100.0,100.0)
theLayer.position=CGPointMake(500.0,500.0);

Explicit Animation

Core Animation also supports an explicit animation model. The explicit animation model requires that you create an animation object, and set start and end values. An explicit animation won’t start until you apply the animation to a layer.The animation doesn’t begin until it is added to the layer.

CABasicAnimation *theAnimation;
 
theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
theAnimation.duration=3.0;
theAnimation.repeatCount=2;
theAnimation.autoreverses=YES;
theAnimation.fromValue=[NSNumber numberWithFloat:1.0];
theAnimation.toValue=[NSNumber numberWithFloat:0.0];
[theLayer addAnimation:theAnimation forKey:@"animateOpacity"];

Starting and Stopping Explicit Animations

You start an explicit animation by sending a addAnimation:forKey: message to the target layer, passing the animation and an identifier as parameters. Once added to the target layer the explicit animation will run until the animation completes, or it is removed from the layer. The identifier used to add an animation to a layer is also used to stop it by invokingremoveAnimationForKey:. You can stop all animations for a layer by sending the layer a removeAllAnimations message.

Layer Actions

Layer actions are triggered in response to: layers being inserted and removed from the layer-tree, the value of layer properties being modified, or explicit application requests. Typically, action triggers result in an animation being displayed.

There's no difference between an implicit animation and an explicit
animation. The only difference is that implicit animations are created
by the layer's -actionForKey: method in response to a property being
changed, while explicit animations are created by your code directly.

This is what happens when a layer property is modified:

1. Finds the "action" object associated with the property. If the
disableActions transaction property is true the action is nil,
otherwise, calls the -actionForKey: method, with the key being the key-
path of the property being changed. -actionForKey: does these things
to try to find a non-nil object: (the first that returns non-nil stops
the others from being tried)

1. calls the -actionForLayer:forKey: delegate method
2. looks in the layer's "actions" property (a dictionary)
3. walks up the "style" hierarchy looking in the "actions" property
of each style dictionary
4. calls the +defaultActionForKey: method.
5. if the key represents an animatable property, creates an animation
object to represent that animation.

any of these steps can return [NSNull null] to stop the search.

2. Calls the -willChangeValueForKey: method

3. Sets the property to its new value wherever that's stored

4. Calls the -didChangeValueForKey: method

5. If the action from step (1) is non-nil, invoke it's -
runActionForKey:object:arguments: method. In the case of CAAnimation,
this invokes the layer's -addAnimation:forKey: method to add the
animation to the layer (the key is the key-path of the changed
property.)

Hopefully that makes it clearer, the important thing is that an
implicit animation is just an explicit animation that was created
within a property setter via the -actionForKey: mechanism,

Defined Search Pattern for Action Keys

根据不同key ,返回要实现的不同效果的动画类,

添加动画,有可能是系统隐形动画不包含的属性动画。

子类

//- (id<CAAction>)actionForKey:(NSString *)event;

代理类:

-(id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event

{

    CVTransition *anim=nil;

    if([event isEqualToString:@"contents"]){

        anim=[CATransitionanimation];

        anim.duration=2;

        anim.timingFunction=[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut];

        anim.type=@"cube";

        anim.subtype=kCATransitionFromRight;

    }

    return anim;

    //不执行任何动画

    //return nil;

}


When the CALayer implementation of actionForKey: is invoked for an identifier the following search pattern is used:

  1. If the layer has a delegate, and it implements the method actionForLayer:forKey: it is invoked, passing the layer, and the action identifier as parameters. The delegate’s actionForLayer:forKey: implementation should respond as follows:

    • Return an action object that corresponds to the action identifier.

    • Return nil if it doesn’t handle the action identifier.

    • Return NSNull if it doesn’t handle the action identifier and the search should be terminated.

  2. The layer’s actions dictionary is searched for an object that corresponds to the action identifier.

  3. The layer’s style property is searched for an actions dictionary that contains the identifier.

  4. The layer’s class is sent a defaultActionForKey: message. It will return an action object corresponding to the identifier, or nil if not found.


action 主要添加动画

动画的子类中添加

- (void)runActionForKey:(NSString *)key
                 object:(id)anObject
              arguments:(NSDictionary *)dict
{
     [(CALayer *)anObject addAnimation:self forKey:key];
}

Overriding an Implied Animation

You can provide a different implied animation for an action identifier by inserting an instance of CAAnimation into theactions dictionary, into an actions dictionary in the style dictionary, by implementing the delegate methodactionForLayer:forKey:, or subclassing a layer class, overriding defaultActionForKey: and returning the appropriate action object.


Transactions

 the two types of transactions Core Animation supports: implicit transactions and explicit transactions.

Implicit transactions are created automatically when the layer tree is modified by a thread without an active transaction, and are committed automatically when the thread's run-loop next iterates.

 When modifying layer properties from threads that don’t have a runloop, you must use explicit transactions.

Explicit transactions are particularly useful when setting the properties of many layers at the same time (for example, while laying out multiple layers), temporarily disabling layer actions, or temporarily changing the duration of resulting implied animations.


[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];
 
 
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
                 forKey:kCATransactionAnimationDuration];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];

[CATransaction begin]; // outer transaction
 
// change the animation duration to 2 seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
                forKey:kCATransactionAnimationDuration];
// move the layer to a new position
theLayer.position = CGPointMake(0.0,0.0);
 
[CATransaction begin]; // inner transaction
// change the animation duration to 5 seconds
[CATransaction setValue:[NSNumber numberWithFloat:5.0f]
                 forKey:kCATransactionAnimationDuration];
 
// change the zPosition and opacity
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
 
[CATransaction commit]; // inner transaction
 
[CATransaction commit]; // outer transaction

Core Animation adds a new convention to key value coding that allows a class to provide a default value that is used when a class has no value set for that key. Both CALayer or CAAnimation support this convention using the class methoddefaultValueForKey:.

To provide a default value for a key you create a subclass of the class and override defaultValueForKey:. The subclass implementation examines the key parameter and then returns the appropriate default value. Listing 1 shows an example implementation of defaultValueForKey: that provides a new default value for the layer property masksToBounds.

Listing 1  Example implementation of defaultValueForKey:

 
+ (id)defaultValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"masksToBounds"])
         return [NSNumber numberWithBool:YES];
 
    return [super defaultValueForKey:key];
}


 The repeatCount specifies the number of times the animation should repeat and can be a fractional number. Setting the repeatCount to a value of 2.5 for a 10 second animation would cause the animation to run for a total of 25 seconds, ending half way through its third iteration. Setting the repeatCount to 1e100f will cause the animation to repeat until it is removed from the layer.


The fillMode property of the timing protocol defines how an animation will be displayed outside of its active duration. The animation can be frozen at its starting position, at its ending position, both, or removed entirely from display. The default behavior is to remove the animation from display when it has completed.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值