6
votes

I am adding some basic animation to a card game I'm working on. (My first iPhone app.)

I am creating a custom UIView class "AnimationContainer", which flips from image1 to image2, while moving from rect1 to rect2. My ultimate intention is to have up to four of these containers doing their transitions simultaneously.

The problem I'm having is that the animation isn't showing image1... so only the last half of the flip transition appears.

However, if I reset the animation first by touching Reset, then everything works perfectly. In other words, if I press Flip again and again, I only get half the transition... but if I press Reset first, then everything works perfectly for one flip.

So, how can I get the animation to reset itself correctly?

Below is the code, a screenshot, and here's a link to the complete: Project Zip File 700k.

alt text

- (void)displayWithImage1 {     //RESET button calls this
    self.frame = rect1;
    [image2 removeFromSuperview];
    [self addSubview:image1];
    [self setNeedsDisplay]; //no help: doesn't force an update before animation
}

- (void)runTheAnimation {     //FLIP button calls this
    [self displayWithImage1]; //<---this is what the reset button calls
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationTransition:transition forView:self cache:NO];
    self.frame = rect2;
    [image1 removeFromSuperview];
    [self addSubview:image2];
    [UIView commitAnimations];
}

Thanks!

1
I've come up with a half-ugly workaround. I added a "dummy" animation and made my class a delegate for its setAnimationDidStopSelector. The dummy animation has a duration of 0.0 and just moves the view to rect1. When the dummy's stop selector is called, there I do the "real" animated flip code from above. Fully functional, and it looks like at least 4 can be running simultaneously. Yay, me. LOL - Rob
Turns out that the workaround can produce up to a half second of delay, so I'm starting a bounty. There must be a way to send a container view two images and have it flip from one to the next all in one transition. - Rob

1 Answers

12
votes

You need a drawing loop to pass in order to redraw the view before performing the animation. This code is an example of "draw this, and when the next event loop comes around, do this other thing." It's not uncommon to do this in UI code. Your first work-around is attempting the same thing, but in a much more complicated way.

- (void)_runTheAnimation {
    // Moved here from -runTheAnimation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationTransition:transition forView:self cache:NO];
    self.frame = rect2;
    [image1 removeFromSuperview];
    [self addSubview:image2];
    [UIView commitAnimations];
}

- (void)runTheAnimation {     //FLIP button calls this
    [self displayWithImage1];
    [self performSelector:@selector(_runTheAnimation) withObject:nil afterDelay:0.0];
}