4

Attempting to toggle both the selected and enabled attribute on a UIButton, therefore creating 4 potential states (Selected & Disabled, Selected & Enabled, Unselected & Disabled, unselected & Enabled).

In viewDidLoad I define the the images for the button states

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.inputToolbar.contentView.leftBarButtonItem setImage:[UIImage imageNamed:BLUE_IMAGE] forState:UIControlStateNormal];
    [self.inputToolbar.contentView.leftBarButtonItem setImage:[UIImage imageNamed:GREY_IMAGE] forState:UIControlStateSelected];
}

In viewWillAppear I conditionally set the enabled attribute along with a property (we'll call self.buttonShouldBeSelected) which then sets the UIButton's selected attribute in its setter. Along with some debugging code in viewDidLoad

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // default control states
    self.inputToolbar.contentView.leftBarButtonItem.enabled = NO;

    if (self.aBoolean) {
         self.buttonShouldBeSelected = [self.aNSNumber boolValue];
    }
}

- (void)setButtonShouldBeSelected:(BOOL)buttonShouldBeSelected
{
    self.inputToolbar.contentView.leftBarButtonItem.selected = buttonShouldBeSelected;
    _buttonShouldBeSelected = buttonShouldBeSelected;
}

- (void)viewDidAppear
{
    NSLog(@"SELECTED: %u", self.inputToolbar.contentView.leftBarButtonItem.selected);
    NSLog(@"ENABLED: %u", self.inputToolbar.contentView.leftBarButtonItem.enabled);
    NSLog(@"STATE: %lu", self.inputToolbar.contentView.leftBarButtonItem.state);
}

This works in all cases aside from one, when the button is disabled and in the selected state. In this case the UI displays the BLUE_IMAGE instead of the selected state's GREY_IMAGE and the button is correctly disabled.

In this case the log results in...

SELECTED: 1
ENABLED: 0
STATE: 6

What am I doing wrong, why is it showing the image for NormalState and what does UIControlState == 6 mean?

user1905842
  • 165
  • 1
  • 13
  • Try replacing UIControlStateSelected with (UIControlStateHighlighted|UIControlStateSelected) – Josh Gafni Jan 14 '15 at 03:06
  • adding UIControlStateHighlighted had no change – user1905842 Jan 14 '15 at 03:22
  • Thanks Josh...while your solution wasn't exactly right, it got me thinking on the right path. I added a 3rd setImage: forState:, setting GREY_IMAGE for (UIControlStateDisabled | UIControlStateSelected). – user1905842 Jan 14 '15 at 03:39

7 Answers7

4

And for Swift 3:

inputToolbar.contentView.leftBarButtonItem.setImage(UIImage(named: GREY_IMAGE), for: [.disabled, .selected])
Morten Gustafsson
  • 1,869
  • 2
  • 24
  • 34
4

I have come in to the same problem. I used property isUserInteractionEnabled instead of isEnabled, so the button can remain status where it was before.

responser
  • 432
  • 4
  • 7
3

Need to add third state declaration

[self.inputToolbar.contentView.leftBarButtonItem setImage:[UIImage imageNamed:GREY_IMAGE] forState:(UIControlStateDisabled | UIControlStateSelected)]
user1905842
  • 165
  • 1
  • 13
1

For Swift:

inputToolbar.contentView.leftBarButtonItem.setImage(UIImage(named: GREY_IMAGE), forState: [.Disabled, .Selected])
twofish
  • 354
  • 4
  • 16
0
[button setImage:[UIImage imageNamed:@"buttonImage.png"] forState:UIControlStateSelected | UIControlStateHighlighted];
Nagarjun
  • 6,557
  • 5
  • 33
  • 51
0

Could you try setting tint color to nil?

[self.inputToolbar.contentView.leftBarButtonItem setTintColor:nil];
sagar.musale
  • 585
  • 1
  • 7
  • 19
0

This is how combining states worked for me in Swift:

let state = UIControl.State.selected.union(UIControl.State.disabled)
button.setImage(image, for: state)
Nadzeya
  • 641
  • 6
  • 16