Please note, this blog entry is from a previous course. You might want to check out the current one.
Use a flip transition to animate choosing cards in the Playing Card game (so that the cards look like they are being flipped over when chosen).
When choosing a card, set that card to its new “future” state for the animation. When the animation is complete reset that change and run the “original” code of updating the game and the user interface:
- (void)touchCard:(UITapGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateEnded) { Card *card = [self.game cardAtIndex:gesture.view.tag]; [UIView transitionWithView:gesture.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ card.chosen = !card.chosen; [self updateView:gesture.view forCard:card]; } completion:^(BOOL finished) { card.chosen = !card.chosen; [self.game chooseCardAtIndex:gesture.view.tag]; [self updateUI]; }]; } }
The complete code is available on github.
Hi,
Thanks for doing this; extremely helpful to someone tyring to learn this.
Could you please explain the completion block? Why would you need to update the UI (again); was it not updated with the animation?
For the transformation I updated only the view, the model does not know about the change yet, thus I have to do that in the completion block … Why I did that? Well, good question. It’s an excellent point, why I should put more comments into my code … It’s quite some time …
Nevertheless, try yourself 😉 Skip the competition code and use its code for the transformation … While it will work for flipping cards, have a look what happens when you flip a matching pair … (Or at least that’s the reason I remember … could be wrong, though …)
I also want to say thanks for putting your solutions out. I’m in a bit of a crunch to get up to speed with iOS so it’s really nice to get some help to keep things moving…since I can’t reach out to Paul or a TA. 🙂
I had the same question as Guy. From my experimentation I was able to do away with the completion block and simply update the model in the animation block. Then call updateUI after the transition call. The affect seems to be the same with less code.
However, for me this doesn’t animate the flip back following a mismatch. It also “flips” the Set cards which seems like a side affect.
Moving the transition into PlayingCardGameViewController.m’s updateView gave a nice result (handles all Playing Card flips and leaves Set cards alone).
– (void)updateView:(UIView *)view forCard:(Card *)card
{
if (![card isKindOfClass:[PlayingCard class]]) return;
if (![view isKindOfClass:[PlayingCardView class]]) return;
PlayingCard *playingCard = (PlayingCard *)card;
PlayingCardView *playingCardView = (PlayingCardView *)view;
playingCardView.rank = playingCard.rank;
playingCardView.suit = playingCard.suit;
if (playingCardView.faceUp != playingCard.chosen) {
[UIView transitionWithView:view
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:nil
completion:nil];
}
playingCardView.faceUp = playingCard.chosen;
}
Please remember, my solutions are a solution, not the solution 😉