【问题标题】:How to remove UIButton's image for certain states?如何在某些状态下删除 UIButton 的图像?
【发布时间】:2013-01-19 21:07:14
【问题描述】:

我正在开发一款纸牌游戏。我希望卡片背面显示图像,卡片正面显示卡片内容。我已经将图像显示在背面,但我不知道在选择它时如何清除它。 (所有 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]];
}
}

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

【问题讨论】:

  • 保罗赫加蒂真棒:D

标签: ios uibutton uiimage cs193p


【解决方案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)
    }
}

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          为其他状态创建透明图像的一种快速方法是分配和分配一个空图像,因为 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];
          

          【讨论】:

          • 我从未见过UIImage *cardFrontImage = [UIImage alloc]; 为什么我们不进行初始化?没有错误吗?我是初学者,你能解释一下吗?谢谢。以及为什么我们不能做到这一点:UIImage *cardFrontImage = nil;
          • 另外,它帮助了我。我认为UIImage *cardFrontImage = [[UIImage alloc] init]; 是正确的方法。顺便说一句,Paul Hegarty 多次说过,alloc 从来没有在没有 init 的情况下使用过。
          • UIImage *cardFrontImage = nil; 不能使用,因为它与[cardButton setImage:nil forState:UIControlStateSelected]; 相同,并且 nil 值默认为 UIControlStateNormal 使用的值。通过给它一个实例化的 UIImage,它会“绘制”这个图像,即使它正在绘制一个没有图像数据的图像。
          【解决方案6】:

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

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

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

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

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

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

          【讨论】:

            【解决方案7】:

            你可以使用标签:

            例如:

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

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

            希望这会有所帮助...

            【讨论】:

            • 谢谢,但问题不在于图像被删除或没有为错误的按钮删除——而是任何按钮的图像都没有被删除,无论它们是什么状态。 :(
            猜你喜欢
            • 2020-12-16
            • 2011-11-24
            • 2013-02-24
            • 1970-01-01
            • 2017-01-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多