Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current CAAnimation transform value

I want to access get the value of the transform scale at a point in time. Here is the animation creation :

    CABasicAnimation *grow = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    grow.toValue = @1.5f;
    grow.duration = 1;
    grow.autoreverses = YES;
    grow.repeatCount = HUGE_VALF;
    [view.layer addAnimation:grow forKey:@"growAnimation"];

I'd like to get, for example when a user presses a button, the current size of the view. Logging the frame or the bounds always returns constant values. Any help would be much appreciated !

like image 700
DCMaxxx Avatar asked Nov 27 '13 14:11

DCMaxxx


3 Answers

In Core Animation if an animation is "in flight" on a layer, the layer has a second layer property known as presentationLayer. That layer contains the values of the in-flight animation.

Edited

(With a nod to Mohammed, who took the time to provide an alternate answer for Swift)

Use code like this:

Objective-C

CGFloat currentScale = [[layer.presentationLayer valueForKeyPath: @"transform.scale"] floatValue];

Swift:

let currentScale = layer.presentation()?.value(forKeyPath: "transform.scale") ?? 0.0

Note that the Swift code above will return 0 if the layer does not have a presentation layer. That's a fail case that you should program for. It might be better to leave it an optional and check for a nil return.

Edit #2:

Note that as Kentzo pointed out in their comment, reading a value from an in-flight animation will give you a snapshot at an instant in time. The new value of the parameter you read (transform.scale in this example) will start to deviate from the reading you get. You should either pause the animation, or use the value you read quickly and get another value each time you need it.

like image 76
Duncan C Avatar answered Nov 07 '22 04:11

Duncan C


The CALayer documentation describes presentationLayer quite clearly:

The layer object returned by this method provides a close approximation of the layer that is currently being displayed onscreen. While an animation is in progress, you can retrieve this object and use it to get the current values for those animations.

like image 31
caughtinflux Avatar answered Nov 07 '22 05:11

caughtinflux


swift version of @Duncan C answer will be:

let currentValue = someView.layer.presentation()?.value(forKeyPath: "transform.scale")
like image 4
MEH Avatar answered Nov 07 '22 03:11

MEH