问题 如何删除某些状态的UIButton图像?


我正在打牌。我希望卡片背面显示图像,卡片前端显示卡片内容。我已经将图像显示在背面,但是当它被选中时我无法弄清楚如何清除它。 (所有run-this-code-when-it-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]];
}
}

关于我做错了什么的想法?


4985
2018-02-05 02:13


起源

Paul Hegarty很棒:D - Dima Deplov


答案:


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

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

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

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

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

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


6
2018-02-05 03:58



那就做到了!谢谢! - Joel Derfner


为其他状态创建透明图像的快捷方法,因为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];

6
2018-03-09 00:04



我没见过 UIImage *cardFrontImage = [UIImage alloc]; 为什么我们不做init?没有错吗?我是初学者,你能解释一下吗?谢谢。为什么我们不能这样做: UIImage *cardFrontImage = nil; - Dima Deplov
它也帮助了我。我认为 UIImage *cardFrontImage = [[UIImage alloc] init]; 是一种正确的方式。顺便说一句,Paul Hegarty多次表示,如果没有init,就不会使用alloc。 - Dima Deplov
啊,好抓; init被错误地省略了。 - Kokaubeam
UIImage *cardFrontImage = nil; 不能使用,因为它会是相同的 [cardButton setImage:nil forState:UIControlStateSelected]; 和nil值默认为UIControlStateNormal使用的值。通过给它一个实例化的UIImage,它将“绘制”这个图像,即使它正在绘制一个没有图像数据的图像。 - Kokaubeam
哦,我明白了,谢谢!) - Dima Deplov


如果你使用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];
        }
    }
}

1
2018-03-28 03:55





你可以使用标签:

例如:

- (IBAction)btnClicked:(id)sender {

if([sender tag]==1){

//do something

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

//do something else
}

确保通过转到属性检查器为按钮设置不同的标签,并将默认值0更改为其他内容...

希望这可以帮助...


0
2018-02-05 02:56



谢谢,但问题不在于图像被删除或没有删除错误的按钮 - 这是因为任何按钮都没有删除图像,无论它们处于什么状态。 :( - Joel Derfner


我发现最简单的解决方案是检查按钮是否被标记为已选中。如果没有,请应用背景图像,否则应用null UIImage。


0
2018-04-11 13:57





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

我现在采用相同的方法,作为OP,并遇到了同样的问题。解决方案是,当选择按钮时,您仍然可以设置图像 未选中 州(至零):

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

而且你永远不会为任何其他状态设置图像。


0
2017-07-01 20:56