161

I set an images for button's states Normal,Highlighted and Selected, but when the button in selected state and I press/highlight it I didn't see my highlighted image but just grayed picture. Is it possible to set an image for highlighted state when the button selected?

my code:

[button setImage:[UIImage imageNamed:@"normal.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"pressed.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];

when I do:

[button setSelected:YES];

and press the button, the "pressed.png" image doesn't select.

5
  • +1 I have the same problem, hope there'll be answers. Commented Apr 8, 2011 at 8:47
  • 3
    Brilliant! Who would ever know you could set images for combinations! Worked like a charm for me! Commented Jul 19, 2011 at 14:24
  • 1
    Awesome!!! your question itself is answer for me... It worked!!! Commented Aug 31, 2012 at 3:05
  • 1
    It works for me with just UIControlStateHighlighted, but I call button.adjustsImageWhenHighlighted = NO; first. Commented Sep 4, 2013 at 20:03
  • This. So much better than the solution I had before. Commented Nov 23, 2013 at 4:48

15 Answers 15

234

I found the solution: need to add addition line

[button setImage:[UIImage imageNamed:@"pressed.png"] forState:UIControlStateSelected | UIControlStateHighlighted];
Sign up to request clarification or add additional context in comments.

9 Comments

Any way to do this via interface builder?
@stephen: Setting the "Background"(image) property of UIButton for different conditions of "StateConfig"(Default/Highlighted/Selected/Disabled) Property works for me.
Ajeet's solution did not work for me. I'd also like to know a way of doing that on IB
Since you can't set this in IB, you can put this in your viewDidLoad method, and it'll be almost as good, since you can then change the image in IB and not have to worry about always updating the code to match. [button setImage:[button imageForState:UIControlStateHighlighted] forState:UIControlStateSelected | UIControlStateHighlighted];
You Can do this in IB. See screenshots in below answer!
|
126

You can do this in the Interface Builder.

Select the UIButton you wish to set in IB for, then go to the Attributes inspector.

In the screenshots, I am using a custom button type, but that does not matter.

Custom Default

enter image description here

enter image description here

6 Comments

Custom or System is actually matters a lot. Play around with both and you'll see.
Not in context of the question.
This does not answer the question. He says the combination of highlighted + selected state
+1 because I totally missed these pull down menus (I used to do everything programmatically until quite recently...)
Mind updating this for Xcode13? "State config" ain't there anymore. Earn upvotes here stackoverflow.com/questions/72855556/…
|
33

Swift 3

// Default state (previously `.Normal`)
button.setImage(UIImage(named: "image1"), for: [])

// Highlighted
button.setImage(UIImage(named: "image2"), for: .highlighted)

// Selected
button.setImage(UIImage(named: "image3"), for: .selected)

// Selected + Highlighted
button.setImage(UIImage(named: "image4"), for: [.selected, .highlighted])

To set the background image we can use setBackgroundImage(_:for:)

Swift 2.x

// Normal
button.setImage(UIImage(named: "image1"), forState: .Normal)

// Highlighted
button.setImage(UIImage(named: "image2"), forState: .Highlighted)

// Selected
button.setImage(UIImage(named: "image3"), forState: .Selected)

// Selected + Highlighted
button.setImage(UIImage(named: "image4"), forState: [.Selected, .Highlighted])

2 Comments

The array version didn't work for me. (at least during setImage)
iOS 10 will dim your normal/selected images, which is nice and looks nice. If you set a selected,highlighted image, it won't automatically dim the latter. Which is a bummer.
29

I think most posters here miss the point completely. I had the same problem. The original question was about the Highlighted state of a Selected button (COMBINING BOTH STATES) which cannot be set in IB and falls back to Default state with some darkening going on. Only working solution as one post mentioned:

[button setImage:[UIImage imageNamed:@"pressed.png"] forState:UIControlStateSelected | UIControlStateHighlighted];

2 Comments

i know but i was somehow not allowed
for some reason I still get the issue even if I set it as above. The only way for me to get a custom image for my control state is to set UIControlStateHighlighted only.
12

If you have a good reason to do that, this will do the trick

add these targets:

[button addTarget:self action:@selector(buttonTouchDown:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(buttonTouchUp:) forControlEvents:UIControlEventTouchUpInside];


-(void)buttonTouchDown:(id)sender{
    UIButton *button=(UIButton *)sender;
    if(button.selected){
        [button setImage:[UIImage imageNamed:@"pressed.png"] forState:UIControlStateNormal];
    }
}

-(void)buttonTouchUp:(id)sender{
    UIButton *button=(UIButton *)sender;
    [button setImage:[UIImage imageNamed:@"normal.png"] forState:UIControlStateNormal];
}

1 Comment

Thank for this, but actually it is too complicated) I'll expect that the button will work as described above
7

In Swift 3.x, you can set highlighted image when button is selected in the following way:

// Normal state
button.setImage(UIImage(named: "normalImage"), for: .normal) 

// Highlighted state (before button is selected)
button.setImage(UIImage(named: "pressedImage"), for: .highlighted)

// Selected state
button.setImage(UIImage(named: "selectedImage"), for:  .selected)

// Highlighted state (after button is selected)
button.setImage(UIImage(named: "pressedAfterBeingSelectedImage"), 
                for:  UIControlState.selected.union(.highlighted))

Comments

7

In swift you can do:

button.setImage(UIImage(named: "selected"), 
                forState: UIControlState.selected.union(.highlighted))

Comments

3

In my case, I have to change the UIButton.Type from .custom to .system

And:

button.setImage(UIImage(named: "unchecked"), for: .normal)
button.setImage(UIImage(named: "checked"), for: [.selected, .highlighted])

When handling tapping:

button.isSelected = !button.isSelected

Comments

2

Correct me if I am wrong. By doing

   [button setSelected:YES];

you are clearly changing the state of the buttons as selected. So naturally by the code you have provided the image will that for the selected state in your case checked.png

3 Comments

not fully understand what do you mean by "clearing changing the state...". this is very simple: I set the images for states described above, add target-action for this button and in method that process my action (control event UIControlEventTouchUpInside) I toggle selected state for the button [button setSelected:YES/NO]. And when the button currently in selected state and I press/highlight it, I see only grayed image, like there was no image setup for this state.
I meant clearly there. Sorry for that. When you press the button first you are setting its state as selected, so that image will be displayed. So if you want to get only highlighted image make its state as highlighted. I am not sure though if I am getting you properly
When I press the button first I state it as highlighted and then when I release it the state will be selected (as I set it in my action method). Than I press it again (button already in selected state) and the state should be changed to highlighted and I should see the pressed.png image but I don't see it in this case.
1

If someone's wondering how this works in Swift, here's my solution:

button.setImage("normal.png", forState: .Normal)
button.setImage("highlighted.png", forState: .Highlighted)
button.setImage("selected.png", forState: .Selected)

var selectedHighLightedStates: UIControlState = UIControlState.Highlighted
selectedHighLightedStates = selectedHighLightedStates.union(UIControlState.Selected)
button.setImage("selectedHighlighted.png", forState: selectedHighLightedStates)

1 Comment

@basegod this is a working solution, but the way Roland Keesom wrote it is much cleaner.
1

Swift 3+

button.setImage(UIImage(named: "selected_image"), for: [.selected, .highlighted])

OR

button.setImage(UIImage(named: "selected_image"), for: UIControlState.selected.union(.highlighted))

It means that the button current in selected state, then you touch it, show the highlight state.

Comments

0

I had problem setting imageView.highlighted = NO; (setting YES worked properly and the image changed to the highlighted one).

The solution was calling [imageView setHighlighted:NO];

Everything worked properly.

Comments

0

Where you want to call from

[button addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside];

The method:

-(void)test:(id)sender{
    UIButton *button=(UIButton *)sender;
    if (_togon){
      [button setTitleColor:UIColorFromRGB(89,89, 89) forState:UIControlStateNormal];
      _togon=NO;
    }
    else{
      [button setTitleColor:UIColorFromRGB(28, 154, 214) forState:UIControlStateNormal];
      _togon=YES;
    }
}

Credit above to Jorge but I improved it a bit giving the full working solution

Comments

0

Xamarin C#

Doing bitwise OR doesn't work for some reason

button.SetImage(new UIImage("ImageNormal"), UIControlState.Normal);
button.SetImage(new UIImage("ImagePressed"), UIControlState.Selected | UIControlState.Highlighted | UIControlState.Focused);

The following works

button.SetImage(new UIImage("ImageNormal"), UIControlState.Normal);
button.SetImage(new UIImage("ImagePressed"), UIControlState.Selected);
button.SetImage(new UIImage("ImagePressed"), UIControlState.Highlighted);
button.SetImage(new UIImage("ImagePressed"), UIControlState.Focused);

Comments

0

If you need the highlighted tint which the OS provides by default when you tap and hold on a custom button for the selected state as well, use this UIButton subclass. Written in Swift 5:

import Foundation
import UIKit
class HighlightOnSelectCustomButton: UIButton {
    override var isHighlighted: Bool {
        didSet {
            if (self.isSelected != isHighlighted) {
                self.isHighlighted = self.isSelected
            }
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.