Re: How to animate the drawing of UIImages inside a drawRect: method of a UIView?
Re: How to animate the drawing of UIImages inside a drawRect: method of a UIView?
- Subject: Re: How to animate the drawing of UIImages inside a drawRect: method of a UIView?
- From: David Duncan <email@hidden>
- Date: Fri, 3 Apr 2009 14:28:35 -0700
On Apr 2, 2009, at 8:11 PM, WT wrote:
25 was just a test. The actual app has 2 interlocking 7x7 grids, so
the number of image views is actually 98. I should explain that this
animated laying out of image views happens only once and, from that
point on, the image views all remain in the same place, though each
image itself is animated. Here's a screen shot to clarify things:
The balls pulsate, growing and shrinking in size, an effect that I
accomplish using UIImageView's -startAnimating, but the animation I
was referring to in my previous posts has to do with adding each
image view to its proper place.
My question boils down to this: if I am going to use -startAnimating
for the pulsation, then each ball *has* to be an instance of
UIImageView, which requires me to add 98 subviews to the superview
and the laying out animation is as I described in the 25-image
example. On the other hand, I could forgo using 98 subviews and do
everything (one-time animated layout *and* animated pulsation)
inside the superview's -drawRect. This second option is where I'm
unsure how to proceed.
The solution I have now (98 subviews) works and is convenient but is
taxing the device, so I'm looking for a better alternative,
performance-wise.
You may see better performance by borrowing a technique from OpenGL -
namely by creating a texture atlas. In Core Animation parlance, you do
this by using a common image for the layer contents and using the
contentsRect property to select a portion of the image. If the balls
in your scene always animate at a particular rate and with particular
parameters, then you can set this up once and forget about it for the
rest of the scene and Core Animation will update the image for you at
an appropriate rate.
The first step is to create a texture atlas and note the normalized
coordinates of each frame (so if you had an image that represented 16
frames, the first one might be at 0.0, 0.0, the second at 0.25, 0.0,
etc each with a 0.25x0.25 size). Setup all your layers (or
UIImageViews if you like) with the same image, and then add a keyframe
animation to the layer that animates the contentsRect to scrub across
the frames like this:
CAKeyframeAnimation *animation = [CAKeyframeAnimation
animationWithKeyPath:@"contentsRect"];
// Media Timing Parameters
animation.duration = kTimeConst * frameCount; // how long to animate
each frame for by number of frames
animation.repeatCount = 1e9; // repeat forever
// Keyframe Parameters
animation.values = [NSArray arrayWithObjects:
[NSValue valueWithCGRect:CGRectMake(0.00, 0.00, 0.25, 0.25)], //
frame 1
[NSValue valueWithCGRect:CGRectMake(0.25, 0.00, 0.25, 0.25)], //
frame 2
[NSValue valueWithCGRect:CGRectMake(0.50, 0.00, 0.25, 0.25)], //
frame 3
... // etc
nil];
animation.calculationMode = kCAAnimationDiscrete; // don't interpolate
values
Then you just add this animation to the layer and your content will
animate its way through the atlas without you needing to do a thing.
--
David Duncan
Apple DTS Animation and Printing
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden