Changing a ongoing animation
Basically, what i'm trying to do is animate a cloud, and then change it's speed and/or direction mid-animation if the wind changes. If it matters, i am controlling the whole thing from a UIViewController, and the cloud exists of a UIView with a CALayer on top of that, which is the cloud itself. I have also tried it with a UIImageView on top.
For the TL:DR types, in short what i'm trying to do is either get the position of a animating view, or stop a animating view using block animations.
And here's the full story. My problem is to get its position during the animation. I am using block animations. Because i only know the speed with which it should move, i need to calculate the time myself by using the distance left. I have tried the following code, and several variations of it:
[[Cloud CloudImage]convertPoint:CGPointMake([[[Cloud CloudImage] presentationLayer] position].x, 0) toLayer:self.layer].x
Where Cloud is the UIView and CloudImage is the CALayer. This was the most complex variation i tried of this, i tried vario开发者_Python百科us simpler ones (with directly asking the Cloud, for example, or with UIView instead of CALayer). However, all it returns is its final value. I read something about this method being broken from 3.2, but being fixed in 4.2; However, it was not fixed when i changed the deployment target to iOS 4.3 instead of 4.0. I am using the 4.3 base sdk.
A few other variations i considered were stopping the animation alltogether for a moment, then getting the position and starting the new animation right away. However, i will need to know a way to stop a block-based animation in its tracks, and i have only found snippets for the older animation system (commitanimations).
The last one i considered was writing my own kind of animation system; The cloud would have a repeating NSTimer at 0.08 seconds or so, and create a 0.08 second core animation each time it fired, for which it uses the speed given to the cloud as a property. However, i fear that any variation of this will have much lower performance, while i need it to be as lightweight as possible, for i have up to 20 of these clouds simultaneously (and sometimes with rain too).
Thanks in advance!
I definitely would roll my own system in this case, and the performance loss versus using built-in animation code can be minimized using CADisplayLink
rather than NSTimer
(CADisplayLink
is directly tied to the on-screen updates timer).
The fact that you have 20 clouds simultaneously doesn't really change things too much, as I presume your intention is to animate those 20 clouds separately using the built in animations already.
If you're unsure of how big of a performance hit it will have on things in the end, you could try simply adding a bunch of clouds (50 or so) using the built in animation and see how sluggish they move, then switching it out to built-in animation code and comparing.
Edit: this discussion on Stack Overflow goes into detail on how to do what you're asking, in case you go that route: Cancel a UIView animation?
Example:
// startAnimating called once to initiate animation loop. might be stopped e.g.
// if game is paused or such
- (void)startAnimating
{
// displayLink = the CADisplayLink for the current animation, if any.
if (displayLink) {
[displayLink invalidate];
[displayLink release];
}
displayLink = [[CADisplayLink displayLinkWithTarget:self
selector:@selector(animationTick:)]
retain];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
// tick method is called at every interval; we want to update things based on
// a delta time (duration), so that if things get bogged down and the updates
// come less often, we don't go into slow motion
- (void)tick:(CADisplayLink *)sender
{
CFTimeInterval duration = sender.duration;
// here, we update the position for all the UIView objects. example:
CGRect cloudFrame;
for (UIView *cloud in clouds) {
cloudFrame = cloud.frame;
cloudFrame.origin.x += windForceX * duration;
cloudFrame.origin.y += windForceY * duration;
cloud.frame = cloudFrame;
}
// here we might update the windForceX and Y values or this might happen somewhere
// else
}
精彩评论