Retired Document
Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid.
Animating the frame of a CALayer.
Q:
When I try to animate the frame
of a CALayer
nothing happens. Why?
A: The frame
property of a CALayer
is a derived property, dependent on the position
, anchorPoint
, bounds
and transform
of the layer. Instead of animating the frame
, you should instead animate the position
or bounds
, depending on what effect you are trying to accomplish.
To move a layer, you can animate the position
as shown in Listing 1.
Listing 1 Animating the position
of a layer.
-(void)moveLayer:(CALayer*)layer to:(CGPoint)point |
{ |
// Prepare the animation from the current position to the new position |
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; |
animation.fromValue = [layer valueForKey:@"position"]; |
// NSValue/+valueWithPoint:(NSPoint)point is available on Mac OS X |
// NSValue/+valueWithCGPoint:(CGPoint)point is available on iOS |
// comment/uncomment the corresponding lines depending on which platform you're targeting |
// Mac OS X |
animation.toValue = [NSValue valueWithPoint:NSPointFromCGPoint(point)]; |
// iOS |
//animation.toValue = [NSValue valueWithCGPoint:point]; |
// Update the layer's position so that the layer doesn't snap back when the animation completes. |
layer.position = point; |
// Add the animation, overriding the implicit animation. |
[layer addAnimation:animation forKey:@"position"]; |
} |
To resize a layer, you would animate the bounds
parameter as shown in Listing 2.
Listing 2 Animating the size of a layer.
-(void)resizeLayer:(CALayer*)layer to:(CGSize)size |
{ |
// Prepare the animation from the old size to the new size |
CGRect oldBounds = layer.bounds; |
CGRect newBounds = oldBounds; |
newBounds.size = size; |
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"]; |
// NSValue/+valueWithRect:(NSRect)rect is available on Mac OS X |
// NSValue/+valueWithCGRect:(CGRect)rect is available on iOS |
// comment/uncomment the corresponding lines depending on which platform you're targeting |
// Mac OS X |
animation.fromValue = [NSValue valueWithRect:NSRectFromCGRect(oldBounds)]; |
animation.toValue = [NSValue valueWithRect:NSRectFromCGRect(newBounds)]; |
// iOS |
//animation.fromValue = [NSValue valueWithCGRect:oldBounds]; |
//animation.toValue = [NSValue valueWithCGRect:newBounds]; |
// Update the layer's bounds so the layer doesn't snap back when the animation completes. |
layer.bounds = newBounds; |
// Add the animation, overriding the implicit animation. |
[layer addAnimation:animation forKey:@"bounds"]; |
} |
You can combine these animations using a CAAnimationGroup
if you need to move and resize a layer at the same time. For more information you will want to read the Core Animation Programming Guide, specifically the sections on Layer Geometry and Transforms , Animation, and Core Animation Extensions To Key-Value Coding as well as the appropriate reference documents. Finally, the Core Animation Cookbook offers sample code for common tasks that you can drop directly into your application.
Document Revision History
Date | Notes |
---|---|
2011-02-08 | Updated for compatibility on Mac OS X and iOS. |
2010-05-27 | Updated the presented technique. |
2008-10-24 | New document that explains how the frame property of a layer interacts with animations. |
Copyright © 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-02-08