Axeva
Axeva

Reputation: 4737

Flip a UIImageView using Blocks

I'm trying to flip a UIImageView using block animations. Many web sites (and answers here on SO) suggest this:

flipTile.image = frontImage;

[UIView transitionWithView: flipTile
                  duration: 2.5f
                   options: UIViewAnimationOptionTransitionFlipFromLeft
                animations:^(void) {
                    flipTile.image = backImage;
                }
                completion:^(BOOL finished) {
                }
 ];

Unfortunately, that's not giving me the result I expect. I get absolutely nothing for the first half of the animation, then the backImage flips in to appearance for the second half of the animation. It's like the frontImage was hidden or transparent -- which it is not.

Something in the transition is messing things up. What am I doing wrong?

Upvotes: 1

Views: 749

Answers (2)

Rob
Rob

Reputation: 437582

This is precisely what transitionWithView was designed for.

The behavior you describe is symptomatic of frontImage being nil (or, as you pointed out, not having been initialized yet). If it is not yet initialized with a valid image and you do the animation, there's nothing for the first half of the animation, and you only see the second half of the animation.

If frontImage is not supposed to be nil, I'd check that (with NSAssert or NSLog). If it's ok for frontImage to be nil, then, if nil set the initial image to a separate blank image, from which it can then animate the full flipping.

Upvotes: 1

Axeva
Axeva

Reputation: 4737

Here's the solution, should anyone else face this problem in the future:

In a nutshell, the animation block is flipping between the current state of my UIImageView, and the state I set in the animations section. With the image for flipTile being set just before the animation block is called, however, the iOS rendering engine does not have a chance to update my UIImageView before the animation starts. Hence I see an animation from the current state of the UIImageView (nil), to the new state (backImage).

To fix the problem, I need to return control back to iOS for a split second to allow the rendering engine to do it's business, then perform the animation.

Here's how I did it:

- (void)giveHint {
    /*
        other work here
    */

    flipTile.image = currentTileImage;

    [self performSelector:@selector(flipTile) withObject:nil afterDelay: 0.1];
}

- (void)flipTile {
    [UIView transitionWithView: flipTile
                      duration: 0.5
                       options: UIViewAnimationOptionTransitionFlipFromLeft
                    animations:^{
                        flipTile.image = newTileImage;
                    }
                    completion:^(BOOL finished) {
                        /*
                            clean up
                        */
                    }
     ];
}

Upvotes: 3

Related Questions