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.

The Role of Action Objects

An action object is an object that responds to an action identifier via the CAAction protocol. Action identifiers are named using standard dot-separated key paths. A layer is responsible for mapping action identifiers to the appropriate action object. When the action object for the identifier is located that object is sent the message defined by the CAAction protocol.

The CALayer class provides default action objects–instances of CAAnimation, a CAAction protocol compliant class–for all animatable layer properties. CALayer also defines the following action triggers that are not linked directly to properties, as well as the action identifiers in Table 1.

Table 1  Action triggers and their corresponding identifiers

Trigger

Action identifier

A layer is inserted into a visible layer-tree, or the hidden property is set to NO.

The action identifier constant kCAOnOrderIn.

A layer is removed from a visible layer-tree, or the hidden property is set to YES.

The action identifier constant kCAOnOrderOut.

A layer replaces an existing layer in a visible layer tree using replaceSublayer:with:.

The action identifier constant kCATransition.

Defined Search Pattern for Action Keys

When an action trigger occurs, the layer’s actionForKey: method is invoked. This method returns an action object that corresponds to the action identifier passed as the parameter, or nil if no action object exists.

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.

Adopting the CAAction Protocol

The CAAction protocol defines how action objects are invoked. Classes that implement the CAAction protocol have a method with the signature runActionForKey:object:arguments:.

When the action object receives the runActionForKey:object:arguments: message it is passed the action identifier, the layer on which the action should occur, and an optional dictionary of parameters.

Typically, action objects are an instance of a CAAnimation subclass, which implements the CAAction protocol. You can, however, return an instance of any class that implements the protocol. When that instance receives the runActionForKey:object:arguments: message it should respond by performing its action.

When an instance of CAAnimation receives the runActionForKey:object:arguments: message it responds by adding itself to the layer’s animations, causing the animation to run (see Listing 1).

Listing 1  runActionForKey:object:arguments: implementation that initiates an animation

 
- (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 the actions dictionary, into an actions dictionary in the style dictionary, by implementing the delegate method actionForLayer:forKey:, or subclassing a layer class, overriding defaultActionForKey: and returning the appropriate action object.

The example in Listing 2 replaces the default implied animation for the contents property using delegation.

Listing 2  Implied animation for the contents property

 
- (id<CAAction>)actionForLayer:(CALayer *)theLayer
                        forKey:(NSString *)theKey
{
    CATransition *theAnimation=nil;
 
    if ([theKey isEqualToString:@"contents"])
    {
 
        theAnimation = [[CATransition alloc] init];
        theAnimation.duration = 1.0;
        theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        theAnimation.type = kCATransitionPush;
        theAnimation.subtype = kCATransitionFromRight;
    }
 
    return theAnimation;
}

The example in Listing 3 disables the default animation for the sublayers property using the actions dictionary pattern.

Listing 3  Implied animation for the sublayers property

// get a mutable version of the current actions dictionary
NSMutableDictionary *customActions=[NSMutableDictionary dictionaryWithDictionary:[theLayer actions]];
 
// add the new action for sublayers
[customActions setObject:[NSNull null] forKey:@"sublayers"];
 
// set theLayer actions to the updated dictionary
theLayer.actions=customActions;

Temporarily Disabling Actions

By default, any time you change an animatable property, the appropriate animation will occur.

You can temporarily disable actions when modifying layer properties by using transactions. See “Temporarily Disabling Layer Actions” for more information.



© 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-10-19)