+2  A: 

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];
}
Rob Napier
Awesome! Thank you so much. I wasn't at all clear that selectors didn't execute immediately. Everything's working great now. The 200 rep bounty was a small price to pay. I've spent 10 hours messing with this.
Rob
Selectors are sent immediately if asked to (-peformSelector:) The method above is -performSelector:withObject:afterDelay:, which schedules on the runloop for the selector to be sent at some point in the future. A delay of 0 effectively means "the next time the run loop iterates." Selectors themselves just describe a message to pass to an object. The act of passing that message is done by the performSelector... methods.
Rob Napier
Cool, I think I understand. Still getting up to speed on Cocoa, Objective-C and all things iPhone... but I'm learning faster now. Thanks again.
Rob