I'm working on a card game. I want the card backs to show an image and the card fronts to show the card contents. I've gotten the image to show on the back, but I can't figure out how to clear it when it's selected. (All the run-this-code-when-it's-selected code is running, so I know it's not a question of not actually changing state.) Here's my code:
-(void)updateUI {
for (UIButton *cardButton in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];
[cardButton setTitle:card.contents forState:UIControlStateSelected];
[cardButton setTitle:card.contents forState:UIControlStateSelected | UIControlStateDisabled];
[cardButton setImage:[UIImage imageNamed:@"cardback.png"] forState:UIControlStateNormal];
//I've tried various permutations of the following three lines, but the image never disappears.
[cardButton setImage:nil forState:UIControlStateSelected];
[cardButton setImage:nil forState:UIControlStateSelected | UIControlStateHighlighted];
[cardButton setImage:nil forState:UIControlStateNormal];
cardButton.selected = card.faceUp;
cardButton.alpha=(card.unplayable ? 0.3:1.0);
[self.scoreLabel setText:[NSString stringWithFormat:@"Score: %d",self.game.score]];
}
}
Any thoughts about what I'm doing wrong?
I am guessing your problem is this (from the Apple Documentation for setImage:forState:
):
In general, if a property is not specified for a state, the default is to use the
UIControlStateNormal
value. If theUIControlStateNormal
value is not set, then the property defaults to a system value. Therefore, at a minimum, you should set the value for the normal state.
So, you cannot simply unset images for some states because the default image will get used.
I see a couple of solutions to this problem:
nil
UIImageView
subview that you set to the card back image. If the card is face down, use setHidden:
to show the subview. If the card is face up, use setHidden:
to hide the subview. I would probably use the – addTarget:action:forControlEvents:
method within your custom button class to register a custom method that shows or hides the card back subview.Note that you could easily take option 2 a step further by displaying the front of the card in a subview as well and then you can easily animate a flip transition between those two subviews so that the card "flips" over when pressed.