0
votes

I have a UIButton that has no title or initial background image. When pressed, the button background image changes and when pressed again, it is set to nil. Now with iOS 6.x, the button completely disappears. Here is my code:

- (IBAction)resetAll: (id) sender {
[self reset];

for (UIView *view in self.view.subviews) {

    if ([[[view class] description] isEqualToString:@"UIRoundedRectButton"]) {
        UIButton *theButton = (UIButton *)view;         

        int nTag = theButton.tag;

        switch (nTag) {
            case 11: {
                theButton.tag = 10;
                [theButton setBackgroundImage:nil forState:UIControlStateNormal];
                break;
            }
            case 21: {
                theButton.tag = 20;
                [theButton setBackgroundImage:nil forState:UIControlStateNormal];
                [theButton setEnabled:YES];
                break;
            }
            case 31: {
                theButton.tag = 30;
                [theButton setBackgroundImage:nil forState:UIControlStateNormal];
                [theButton setEnabled:YES];
                break;
            }
            case 41: {
                theButton.tag = 40;
                [theButton setBackgroundImage:nil forState:UIControlStateNormal];
                [theButton setEnabled:YES];
                break;
            }
            case 51: {
                theButton.tag = 50;
                [theButton setBackgroundImage:nil forState:UIControlStateNormal];
                [theButton setEnabled:YES];
                break;
            }
        }
    }
}
return;

This code works fine:

- (IBAction)ButtonClicked: (id) sender {
UIButton *btn = (UIButton *)sender;

// Get the current tag value
int currentTag = [sender tag];

// Toggle the check buttons
if (currentTag == 10 || currentTag == 20 || currentTag == 30 || currentTag == 40 || currentTag == 50) {
        [btn setBackgroundImage:[UIImage imageNamed:@"check.png"] forState:UIControlStateNormal];
        btn.tag = ++currentTag;
}

else
    if (currentTag == 11 || currentTag == 21 || currentTag == 31 || currentTag == 41 || currentTag == 51) {
        [btn setBackgroundImage:nil forState:UIControlStateNormal];
        btn.tag = --currentTag;
}

[self calculate];

Any suggestions or help would be appreciated!

3

3 Answers

1
votes

Instead of changing the background image of the button in the UIControlStateNormal, why not instead just change states of the button? If you created the button programmatically, you just need to add the line

[btn setBackgroundImage:[UIImage imageNamed:@"check.png"] forState:UIControlStateSelected];

Then, when pressed and you want it to be the arrow image:

[btn setSelected:YES];

and to set it back to the default appearance:

[btn setSelected:NO];

If you made the button in a XIB, you can set the state images by changing the state config to Selected and set the image there.

0
votes

Here is the final code implementing DOC's answer. I set the default and selected state in interface builder:

- (IBAction)ButtonClicked: (id) sender {
UIButton *btn = (UIButton *)sender;

if ([btn isSelected ]) {
    [btn setSelected:NO];
} else {
    [btn setSelected:YES];
}

[self calculate];
}


- (IBAction)resetAll: (id) sender {
[self reset];

for (UIView *view in self.view.subviews) {

    if ([[[view class] description] isEqualToString:@"UIRoundedRectButton"]) {
        UIButton *theButton = (UIButton *)view;         

        [theButton setSelected:NO];

    }
}
0
votes

Just an additional answer in case (like me) there is already a good amount of logic around the selected state of the button (parent class gives state to the view based on this). If you need the button to start in an un-selected state with an image and change state to selected with the no image, then you can add a generated blank image to the selected state like so.

            //Make a stupid blank image because setting to nil on a state doesn't work.
            UIGraphicsBeginImageContextWithOptions(CGSizeMake(23, 23), NO, 0.0);
            UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();

            UIImage *buttonNonSelectedImage = [UIImage imageNamed:@"video-slomo"];
            [self.myButton setBackgroundImage:buttonNonSelectedImage forState:UIControlStateNormal];
            [self.mybutton setBackgroundImage:blank forState:UIControlStateSelected];
            [self.myButton addTarget:self
                                    action:@selector(onMyButtonPress)
                          forControlEvents:UIControlEventTouchUpInside];
            self.myButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
            [self.playRateButton setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
            [self.view addSubview:self.myButton];

Then, in your button action you can just change the state (and in my case add text).

- (void)onMyButtonPress
{
    if (self.myButton.isSelected) {
        [self.myButton setSelected:NO];
    }
    else {
        [self.myButton setTitle:@"Selected"]
                              forState:UIControlStateSelected];
        [self.myButton setSelected:YES];
    } 
}

The accepted answer works in most cases, I just needed the selected state for other tracking info. Happy programming.