10

我正在做一个纸牌游戏。我希望卡片背面显示图像,卡片正面显示卡片内容。我已经将图像显示在背面,但我不知道在选择它时如何清除它。(所有 run-this-code-when-it's-selected 代码都在运行,所以我知道这不是没有实际改变状态的问题。)这是我的代码:

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

关于我做错了什么有什么想法吗?

4

7 回答 7

6

我猜你的问题是这样的(来自 Apple 文档setImage:forState:):

通常,如果没有为状态指定属性,则默认使用该UIControlStateNormal值。如果UIControlStateNormal未设置该值,则该属性默认为系统值。因此,您至少应该设置正常状态的值。

因此,您不能简单地取消设置某些状态的图像,因为将使用默认图像。

我看到了这个问题的几个解决方案:

  1. 对要显示的状态使用透明图像,而不是nil
  2. 为您的卡片提供UIImageView您设置为卡片背面图像的子视图。如果卡片面朝下,用于setHidden:显示子视图。如果卡片正面朝上,用于setHidden:隐藏子视图。我可能会使用– addTarget:action:forControlEvents:自定义按钮类中的方法来注册显示或隐藏卡片背面子视图的自定义方法。

请注意,您可以通过在子视图中显示卡片的正面来轻松地采取选项 2,然后您可以轻松地为这两个子视图之间的翻转过渡设置动画,以便卡片在按下时“翻转”。

于 2013-02-05T03:58:21.483 回答
6

为其他状态创建透明图像的一种快速方法是分配和分配一个空图像,因为 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];
于 2013-03-09T00:04:56.317 回答
1

如果你使用 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];
        }
    }
}
于 2013-03-28T03:55:57.743 回答
1

我找到的最简单的解决方案是检查按钮是否被标记为选中。如果不是,则应用背景图像,否则应用 null UIImage。

于 2013-04-11T13:57:47.973 回答
1

派对迟到了,我不能投票支持 MultiColour Pixel 的答案,或者评论它,我想是因为我是新来的,没有任何声誉。但这确实是最好和最简单的方法;无需透明图像或其他视图。

我现在和 OP 一样学同样的课程,遇到了同样的问题。解决方法是,当按钮被选中时,你仍然将图像设置为未选中状态(为 nil):

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

而且您永远不会为任何其他州设置图像。

于 2013-07-01T20:56:51.407 回答
1

以防你像我一样对 Objective C 感到厌烦。这是 Sharon 和 MultiColourPixel 用 Swift 实现的解决方案。

func removeImageIfSelected(myButton: UIButton) {
    if myButton.isSelected {
        //set nil for .normal so there isn't a default value for Swift to use
        self.setImage(nil, for: .normal) 
    } else {
        self.setImage(UIImage(systemName: "checkmark.circle.fill"), for: .normal)
    }
}
于 2021-11-11T19:41:18.547 回答
0

您可以使用标签:

例如:

- (IBAction)btnClicked:(id)sender {

if([sender tag]==1){

//do something

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

//do something else
}

确保通过转到 Attributes Inspector 为按钮设置不同的标签并将默认值 0 更改为其他值...

希望这可以帮助...

于 2013-02-05T02:56:09.593 回答