I guess I have to convert the CGRect into an object to pass it to fromValue?
This is how I try it, but it doesn't work:
CABasicAnimation *frameAnimation = [CABasicAnimation animationWithKeyPath:@"frame"]; frameAnimation.duration = 2.5; frameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; frameAnimation.fromValue = [NSValue valueWithCGRect:myLayer.frame]; frameAnimation.toValue = [NSValue valueWithCGRect:theNewFrameRect]; [myLayer addAnimation:frameAnimation forKey:@"MLC"];
Layer animations work much like view animations; you simply animate a property between a start and an end value over a defined period of time and let Core Animation take care of the rendering in between.
Animation layers let you create and blend multiple levels of animation in a scene. You can create layers to organize new keyframe animation, or to keyframe on top of existing animation without overwriting the original curves.
SwiftUI has built-in support for animations with its animation() modifier. To use this modifier, place it after any other modifiers for your views, tell it what kind of animation you want, and also make sure you attach it to a particular value so the animation triggers only when that specific value changes.
An object that provides basic, single-keyframe animation capabilities for a layer property.
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
:
-(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:
-(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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With