RSS

Instantaneous Frame of Moving Core Animation Views

For this Cocoa Code Snippet, I’d like to post a little clarification that caused me some grief a day ago. I was working on a Core Animation enabled view (in a Cocoa Touch project but this post applies to normal Cocoa as well). This view was animating after I set its frame using the following command inside an animation context:

1
2
3
4
UIView *v; // instantiated elsewhere
CGRect r = v.frame;
r.origin.y += 100;
v.frame = r;

This should make sense; it just simply moves the UIView from its current position down 100 pixels. Here’s where my problem came in. What if I wanted to find out where this view was during the animation? A simple call to its frame property returns the final position CGRect and not the instantaneous one.

1
2
// sometime during animation
CGRect curRect = v.frame;

For example, if your animation was a 10 second animation, you would expect at 5 seconds that the rect returned from v.frame would be 50 pixels below the starting frame. In fact, the rect returned would be the rect 100 pixels below.

After this, you might think you should query the layer of the UIView like below:

1
CGrect curRect = v.layer.frame;

This turns out to not work either. This failure is because you are setting the property of the frame and it stays that way even throughout the animation. You need to access a different CGRect to find the instantaneous frame. This makes sense, but is not quite clear in the documentation. What you really are looking for is this:

1
CGRect curRect = [[v.layer presentationLayer] frame];

This returns to us the actual instantaneous frame of the view. From the Apple docs:

Discussion
This method provides a close approximation to the version of the layer that is currently being displayed. The sublayers, mask, and superlayer properties of the returned layer return the presentation versions of these properties. This pattern carries through to the read-only layer methods. For example, sending a hitTest: message to the presentationLayer will query the presentation values of the layer tree.

I hope this tip helps you from spending too much time solving this problem. If you have any comments, please feel free to comment below.

  • lamfan
    If I using UITouch [touch view] to detect the animation UIView,

    How can I update the [touch view] location?

    It seem the frame always stop at first location and finish at final location,

    How can I update it during the animation?
  • Hector
    Thank you very, very much!
  • Name
    Also, don't forget to add QuartzCore framework to your project and reference it in the header file of your class

    #import <QuartzCore/QuartzCore.h>
  • Alex
    It doesn't work for me. I have an UIImageView moving...
  • adasport123
    ADA sport will unite the world. Thanks to the Internet and mobile phones, there are no political, religious, bureaucratic or territorial borders
  • ada
    Thank you for share this code, this post is great...
  • I comment of the great ADA sport will unite the world. Thanks to the Internet and mobile phones, there are no political, religious, bureaucratic or territorial borders
blog comments powered by Disqus
« I’m Now Officially More Popular than Dustin Hoffman. | GrabUp: Simply Amazing »