Как удалить изображение UIButton для определенных состояний?

Я работаю над карточной игрой. Я хочу, чтобы обратная карточка карты отображала изображение и фронты карты, чтобы показать содержимое карты. Я получил изображение, чтобы показать его сзади, но я не могу понять, как его очистить, когда он выбран. (Весь исполняемый код run-this-code-when-it работает, поэтому я знаю, что это не вопрос о не меняющемся состоянии.) Здесь мой код:

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

Любые мысли о том, что я делаю неправильно?

Ответ 1

Я предполагаю, что ваша проблема такова (из документации Apple для setImage:forState:):

В общем случае, если свойство не указано для состояния, по умолчанию используется значение UIControlStateNormal. Если значение UIControlStateNormal не установлено, то по умолчанию значение по умолчанию соответствует системному значению. Поэтому, как минимум, вы должны установить значение для нормального состояния.

Таким образом, вы не можете просто отключить изображения для некоторых состояний, потому что изображение по умолчанию будет использоваться.

Я вижу пару решений этой проблемы:

  • Используйте прозрачное изображение для состояний, которые вы хотите показать, а не nil
  • Дайте вашим картам подтекст UIImageView, который вы установили для обратного изображения карты. Если карта лицевой стороной вниз, используйте setHidden:, чтобы отобразить подпункт. Если карта лицевой стороной вверх, используйте setHidden:, чтобы скрыть подвью. Я бы, вероятно, использовал метод – addTarget:action:forControlEvents: в вашем пользовательском классе кнопок для регистрации настраиваемого метода, который отображает или скрывает подзапрос карты.

Примечание, что вы можете легко сделать опцию 2 еще на шаг, указав переднюю часть карты в подвью, а затем вы можете легко анимировать переброс между этими двумя областями, чтобы карта "переворачивается" при нажатии.

Ответ 2

Быстрый способ создания прозрачного изображения для других состояний, поскольку nil по умолчанию будет иметь значение UIControlStateNormal, заключается в распределении и назначении пустого изображения:

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

Ответ 3

Если вы используете setBackgroundImage, это будет нормально. вот мой код.

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

Ответ 4

Вы можете использовать теги:

Например:

- (IBAction)btnClicked:(id)sender {

if([sender tag]==1){

//do something

}
if([sender tag]==2){

//do something else
}

убедитесь, что вы установили разные теги для кнопок, перейдя в Attributes Inspector и изменив значение по умолчанию 0 на что-то еще...

Надеюсь, что это поможет...

Ответ 5

Самое простое решение, которое я нашел, это проверить, была ли кнопка отмечена как выбрана. Если нет, примените фоновое изображение, иначе примените нулевой UIImage.

Ответ 6

Поздно к вечеринке, и я не могу проголосовать за MultiColour Pixel ответ или прокомментировать это, я думаю, потому что я здесь новичок и не имею никакой репутации. Но это самый лучший и самый простой подход; нет необходимости в прозрачных изображениях или дополнительных представлениях.

Сейчас я беру тот же курс, что и OP, и столкнулся с той же проблемой. Решение заключается в том, что при выборе кнопки вы все равно устанавливаете изображение для состояния невыделенное (в ноль):

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

И вы никогда не устанавливаете изображение для какого-либо другого состояния.