views:

284

answers:

1

I am starting to learn to use UIView animation. So I wrote the following lines:

 [UIView beginAnimations:nil context:NULL];

 [UIView setAnimationDuration:2.0];
 [UIView setAnimationRepeatCount:2];
 [UIView setAnimationRepeatAutoreverses:YES];

 CGPoint position = greenView.center;
 position.y = position.y + 100.0f;
 position.x = position.x + 100.0f;
 greenView.center = position;

 [UIView commitAnimations];

In this case, the UIView (a green box) moved back and fore 2 times. So far so good, BUT I found out that after the moving twice, the green box ended up jumped to the "new position" (position.x + 100.0f, position.y + 100.0f) instead of going back to the original position (position.x, position.y). That makes the animation look pretty odd (like after the box swing back to the original position caused by setAnimationRepeatAutoreverses, it jumps back to the new position in the last microsecond!)

What is the best way to make the green box NOT jump to the new position at the very last minute?

A: 

I've had exactly the same issue with using UIView animations on the alpha property. The worst part is that the animation jumps to the "final" position before the animationDidStop: delegate message is sent, which means you can't manually set the original state there.

My solution was to use the animationDidStop delegate messages to create a new animation block, and string them all together:

- (void)performAnimation
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(phase1AnimationDidStop:finished:context:)];

    // Do phase 1 of your animations here
    CGPoint center = someView.center;
    center.x += 100.0;
    center.y += 100.0;
    someView.center = center;

    [UIView commitAnimations];
}

- (void)phase1AnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(phase2AnimationDidStop:finished:context:)];

    // Do phase 2 of your animations here
    CGPoint center = someView.center;
    center.x -= 100.0;
    center.y -= 100.0;
    someView.center = center;

    [UIView commitAnimations];
}

- (void)phase2AnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    // Perform cleanup (if necessary)
}

You can string together as many animation blocks as you want this way. It seems wasteful code-wise, but until Apple give us a -[UIView setAnimationFinishesInOriginalState:] property or something similar, this the only way that I've found to solve this problem.

Nick Forge
Actually, if I directly follow your code, the view will continuously flying towards the upper left hand corner. We don't really need to create an animation. Just do -100 for both x and y of the center should be enough.
I'm not sure what you mean - can you clarify what's wrong with the code I've given?
Nick Forge