¿Cómo eliminar la image de UIButton para ciertos estados?

Estoy trabajando en un juego de cartas. Quiero que los respaldos de la tarjeta muestren una image y los frentes de la tarjeta para mostrar el contenido de la tarjeta. Obtuve la image para mostrar en la parte posterior, pero no puedo imaginar cómo borrarla cuando se selecciona. (Se está ejecutando todo el código run-this-code-when-it's-selected, así que sé que no es una cuestión de no cambiar el estado). Aquí está mi código:

-(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]]; } } 

¿Alguna idea sobre lo que estoy haciendo mal?

Estoy adivinando que su problema es este (de la Documentación de Apple para setImage:forState: :

En general, si una propiedad no se especifica para un estado, el valor pnetworkingeterminado es usar el valor UIControlStateNormal . Si el valor UIControlStateNormal no está establecido, entonces la propiedad tiene un valor de sistema pnetworkingeterminado. Por lo tanto, como mínimo, debe establecer el valor para el estado normal.

Por lo tanto, no puede simplemente desensamblar imágenes para algunos estados porque se usará la image pnetworkingeterminada.

Veo un par de soluciones a este problema:

  1. Use una image transparente para los estados que desea mostrar en lugar de los nil
  2. Dele a sus tarjetas una subvista UIImageView que configure en la image posterior de la tarjeta. Si la tarjeta está boca abajo, use setHidden: para mostrar la subvista. Si la tarjeta está boca arriba, use setHidden: para ocultar la subvista. Probablemente use el – addTarget:action:forControlEvents: dentro de su class de button personalizada para registrar un método personalizado que muestre u oculte la subvista posterior a la tarjeta.

Tenga en count que fácilmente podría tomar la opción 2 un paso más allá al mostrar la parte frontal de la tarjeta en una subvista también y luego puede animar fácilmente una transición de giro entre esas dos subvistas para que la tarjeta "cambie" al presionarse.

Una manera rápida de crear una image transparente para los otros estados, ya que nil por defecto será el valor de UIControlStateNormal, es asignar y asignar una image vacía:

 UIImage *cardBackImage = [UIImage imageNamed:@"cardback.png"]; UIImage *cardFrontImage = [[UIImage alloc] init]; [cardButton setImage:cardBackImage forState:UIControlStateNormal]; [cardButton setImage:cardFrontImage forState:UIControlStateSelected]; [cardButton setImage:cardFrontImage forState:UIControlStateSelected|UIControlStateDisabled]; 

Si usa setBackgroundImage, eso estará bien. aquí está mi código

 - (void)updateUI { for (int i=0; i < self.cardButtons.count; i++) { Card *card = [self.game cardAtIndex:i]; UIButton *cardButton = self.cardButtons[i]; [cardButton setTitle:card.contents forState:UIControlStateSelected]; [cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled]; cardButton.selected = card.isFaceup; cardButton.enabled = !card.isUnplayable; cardButton.alpha = card.isUnplayable ? 0.3 : 1.0; //handle flipcard backgroundimage changes; UIImage *backgroundImage = (!cardButton.selected) ? [CardGameViewController cardBackgroundImage] : nil; [cardButton setBackgroundImage:backgroundImage forState:UIControlStateNormal]; [self updateScoreLabel:self.game.score]; NSArray *matchCards = [self.game.matchCards lastObject]; if (matchCards) { UIColor *color = [self getOneMatchColor]; for (NSNumber *matchCardIndex in matchCards) { NSUInteger index = [matchCardIndex integerValue]; UIButton *matchCardButton = self.cardButtons[index]; if (color) matchCardButton.backgroundColor = color; } [self.game.matchCards removeLastObject]; } } } 

Puedes usar tags:

Por ejemplo:

 - (IBAction)btnClicked:(id)sender { if([sender tag]==1){ //do something } if([sender tag]==2){ //do something else } 

asegúrese de configurar tags diferentes para los botones yendo al Inspector de attributes y cambie el valor pnetworkingeterminado de 0 a otra cosa …

Espero que esto ayude…

La solución más simple que encontré fue comprobar si el button estaba marcado como seleccionado. Si no es así, aplique una image de background, de lo contrario aplique un UIImage nulo.

Tarde a la fiesta, y no puedo votar la respuesta de MultiColour Pixel, o comentar sobre ella, supongo que porque soy nuevo aquí y no tengo ninguna reputación. Pero ese es de hecho el mejor y más simple enfoque; No hay necesidad de imágenes transparentes o vistas adicionales.

Estoy tomando el mismo curso ahora, como el OP, y me topé con el mismo problema. La solución es que cuando se selecciona el button, usted todavía configura la image para el estado no seleccionado (en nil):

 UIImage *image = [UIImage imageNamed:@"cardback.png"]; // ... [cardButton setImage:(card.isFaceUp ? nil : image) forState:UIControlStateNormal]; 

Y nunca se establece una image para ningún otro estado.