UIButton image goes grey on press - ios

I've gone through all the other questions concerning button color changes. Here's the situation, I have a button that when pressed causes a view to slide out. Before press the button's image is white, once pressed goes grey (this is acceptable), but when pressed again to return to original location, the image is still grey. I want it back to white and have tried using UIControlStateNormal, Disabled, etc with no success.
[self.button setImage:[UIImage imageNamed:#"someImage"] forState:UIControlStateNormal];
this has been changed to all UIControl types. currently it is set as:
[self.menu setImage:[UIImage imageNamed:#"menu"] forState:UIControlStateNormal];
[self.menu setImage:[UIImage imageNamed:#"menu"] forState:UIControlStateSelected | UIControlStateHighlighted];
and still no luck. Any suggestions?

You can disable adjusting colours of button's subviews by setting property
myButton.adjustsImageWhenHighlighted = false

you have to set the same image for both states of the button : -
self.button.setImage(ImageName, for: .normal)
self.button.setImage(ImageName, for: .highlighted)

The code you have shown simply declares which image the button will be depending on different states, however you will need to physically change the state of the button too so these images can be used for each state.
What I mean by this, is if you have the button show a different image for when the button is selected, you will need to change the button state to selected. To return the image to the original unselected image, you will need change the state back to unselected. For example, let's say within your viewDidLoad method you have the following code to declare the images for each of the button states:
//Set for normal state
[self.button setImage:[UIImage imageNamed:#"normalImage.png"] forState:UIControlStateNormal];
//Set for selected state
[self.button setImage:[UIImage imageNamed:#"selctedImage.png"] forState:UIControlStateSelected];
Now within your IBAction method you can toggle between the states
-(IBAction*)yourButtonIsPressed:(id)sender{
if (!self.button.selected){ //This is checking button state
//The code will run in here if the button is in a normal, unselected state. This is where you have you method here to slide in view etc
//Now change the button to a selected state
self.button.selected = YES;
}else{
//The code will now run in here if the button is already in a selected state and this is where you place your method to return the view etc
//Now set the button back to an unselected state
self.button.selected = NO;
}
}
I hope this helps

It was something completely overlooked. I had the view opacity set. so:
self.layer.opacity = .60;
was the issue. Once I commented that line out, the button works like a charm. Thanks for the help Jim.

If you created the button programmatically make sure to set the type and change the image render mode to use original to maintain the image color.
let image = UIImage(named: "someImage").withRenderingMode(.alwaysOrigianl)
let button = UIButton(type: .system)

Related

Unable to change UIButton image inside UITableViewCell

I have a custom UITableViewCell created in a xib and have assigned it a class file of it's own. I have assigned a background image to a UIButton inside this custom cell in IB. In my ViewController where I have a UITableView that uses this cell, I have the below code.
_yesNoCell = (YesNoCell *)[tableView dequeueReusableCellWithIdentifier:#"YesNoCell"];
// Below code is not working
[_yesNoCell.btnYes setImage:[UIImage imageNamed:#"action_selected"] forState: UIControlStateHighlighted];
[_yesNoCell.btnYes addTarget:self action:#selector(btnYesTap:) forControlEvents:UIControlEventTouchUpInside];
Everything works fine, and the btnYesTap method gets called as expected. The background image set in IB shows up, however, what I want is to set a different image when the button is pressed down (not released) i.e the UIControlStateHighlighted. The code above is not working.
I even tried add an action to the button as :
[_yesNoCell.btnYes addTarget:self action:#selector(changeImage:) forControlEvents:UIControlEventTouchDown];
And change the image in changeImage method, but it didn't work.
I referred to similar posts on SO, but none of them seem to have a solution. Referred links : One Two Three
Any help is greatly appreciated.
Actually you setting the button image at Highlighted state but your button is at normal (default) state. So change your button state as like below.
Swift 4
let myImg = UIImage(named: "your-img-name") // your image
myButton.setImage(myImg, for: .highlighted) // set button image for state
myButton.isHighlighted = true // change button state
Objective-C
UIImage *myImg = [UIImage imageNamed:#"your-img-name"];
[myButton setImage:myImg forState:UIControlStateHighlighted];
[myButton setHighlighted:true];
You can do it like that using UIControlStateSelected | UIControlStateHighlighted
[_yesNoCell.btnYes setImage:[UIImage imageNamed:#"action_selected"] forState:UIControlStateSelected | UIControlStateHighlighted];

UIButton not Blinking on Touch

I have a UIButton, created programmatically, inside a UIView (no other levels to the hierarchy). The button does respond to the touchUpInside event properly, but, for some reason, the text isn't exhibiting its normal "blink" behavior when touched. I'd like to get that back, if anyone knows what could cause this.
Other notes: I have userInteractionEnabled = TRUE and there are no custom animations in my code. Relevant instantiation code (UIColor names are from a custom category):
self.loginButton = [[UIButton alloc] init];
self.loginButton.backgroundColor = [UIColor MPBlackColor];
[self.loginButton setTitle:#"LOG IN" forState:UIControlStateNormal];
[self.loginButton setTitleColor:[UIColor MPGreenColor] forState:UIControlStateNormal];
self.loginButton.titleLabel.font = [UIFont fontWithName:#"Oswald-Bold" size:24.0f];
The problem is that your custom color for the normal state applies also for the highlighted state, unless you give it a separate color for the highlighted state. This is true of all button state related values.
Apply a color for both normal and highlighted button state. In Swift:
loginButton.setTitleColor(.green, for: .normal)
loginButton.setTitleColor(.green, for: .highlighted)
Note: the same logic applies to a blinking button with an image. You should set both .normal and .highlighted states

UIButton background image change from another button

Is it possible that I can change the background image of some button when I click on another button?
I basically have 10 buttons, and I want the user to know which button is currently clicked. So what happens is each button has 2 images. One for selected and one for not selected.
I want to create a function which will reset the background images of all the buttons. And in the method for each button, I will add this reset function and then change the background image of that specific button.
Can someone suggest how is that possible?
I know how to change the background image of a button when that button is clicked.
This how my buttons look:
- (IBAction)posterButton:(id)sender {}
- (IBAction)colorInvertButton:(id)sender {}
etc..
Look up the documentation for UIButton: configure each button like this:
[button setControlImage:selectedImage forState:UIControlStateSelected];
[button setControlImage:unselectedImage forState:UIControlStateNormal];
^^this can also be done in interface builder btw.
There are also the states UIControlStateNormal | UIControlStateHighlighted and UIControlStateSelected | UIControlStateHighlighted, but this is optional.
A button also has a selected state, inherited from UIControl.
If you want to have only one selected button at a time, try this (_selectedButton should be declared as an instance variable):
- (UIButton *)selectedButton {
return _selectedButton;
}
- (void)setSelectedButton:(UIButton *)b {
if(b != _selectedButton) {
_selectedButton.selected = NO;
b.selected = YES;
_selectedButton = b;
}
}

Changing a UIButton's image when it's tapped

I have a UIButton that I am programmatically creating and adding to a UITableViewCell.
I have successfully set it up so that if you tap the button and keep holding it down, it will change to the image that I have set for the "highlighted state", but this is not good enough.
When the user taps the button, I need it to completely change to the new image. If the user taps the button again, I want it to change back to the original image.
I want the image to change every time they tap. Right now it changes if they tap and keep holding it down, but it switches back to the original image as soon as they are done holding it down.
Here is the code that I have so far for my buttons:
UIImage *addFriendButtonImage = [UIImage imageNamed:#"SliderThumb-Normal-G"];
UIImage *addFriendButtonImageHighlighted = [UIImage imageNamed:#"SliderThumb-Normal"];
UIButton *addFriendButton = [[UIButton alloc]init];
addFriendButton.frame = CGRectMake(237, -10, 64, 64);
[addFriendButton setImage:addFriendButtonImage forState:UIControlStateNormal];
[addFriendButton setImage:addFriendButtonImageHighlighted forState:UIControlStateHighlighted];
I also tried setting the state for the new image to "UIControlStateSelected" but all that does it make the original image a little darker. It doesn't even change to the new image, and once again it only shows it's effect if you are holding the button down.
Set the image for both the UIControlStateHighlighted and UIControlStateSelected states:
[addFriendButton setImage:addFriendButtonImage forState:UIControlStateNormal];
[addFriendButton setImage:addFriendButtonImageHighlighted forState:UIControlStateHighlighted];
[addFriendButton setImage:addFriendButtonImageHighlighted forState:UIControlStateSelected];
Then listen for UIControlEventTouchUpInside:
[addFriendButton addTarget:self action:#selector(handleTouchUpInside:) forControlEvents:UIControlEventTouchUpInside];
Then update the selected state:
- (void)handleTouchUpInside:(UIButton *)sender {
sender.selected = !sender.selected;
}
What you want is to set new image with [addFriendButton setImage:someImage forState:UIControlStateNormal]; every time the user taps on addFriendButton (look for event UIControlEventTouchUpInside).
If you want you can still assign appropriate highlight image on [addFriendButton setImage:someImage_highlighted forState:UIControlStateHighlighted];
You need to create an IBAction method for your button. If you are using a storyboard to design your view controllers go to the respective view controller in the assistant editor (tap on the icon in the upper right corner of the Xcode window), CTRL+drag the a line from the button to the .h file of your view controller's class like this:
Select Action and enter a named for the method like touchUpInsideButton.
Repeat the same steps to create a property for your button. (But select Outlet instead of Action and give your button a name like myButton.) Now you should have these two lines in your .h file:
#property (strong, nonatomic) IBOutlet UIButton *myButton;
- (IBAction)touchUpInsideButton:(id)sender;
Now go to the .m file of your view controller. Search for the newly created action method - (IBAction)touchUpInsideButton:(id)sender and enter the following code to change the button's image when the user taps the button:
- (IBAction)touchUpInsideButton:(id)sender {
UIImage *myImage = [UIImage imageNamed:#"myImageName"];
[self.myButton setImage:myImage forState:UIControlStateNormal];
}
(You can put any code inside this method that is executed whenever the user taps the button.)
I would recommend this method if you are using a storyboard. If not please refer to #Corey's reply.

UIButton and selected highlight state

The UIButton has a normal/default, highlighted, and selected image. I then have a IBAction method that is called on Touch Down. The method changes the highlighted image depending if it's selected. But when the button is selected, the method is called and so the highlight image is changed, however what is displayed is the normal/default image with a tint. I have tested that image used is in not nil. What happens is when the UIButton in a selected state is pressed displays the normal state with a tint. Why is it not using the highlight image and is there another way of showing a selected highlight image?
Why do you set the highlighted state in the IBAction method? You only need to set the highlighted image for you button when you create it. It will switch automatically. Adding a tint when selected is the default behavior of 'selection' when no highlighted image is assigned.
if your using Interface Builder, just assign the highlighted image there.
Im assuming your looking for normal button selection behavior with your IBAction method set to the touchUpInside event.
I got around this problem by using the selected state and notifications (not via the UI). When a notification is called I change image for the default state, change the selected state and then change the image for selected state.
Update:
I came up with a much better idea from another question that was doing something similar to me. The way to do it is to things in setSelected
- (void)setSelected:(BOOL)selected
{
if ( selected )
{
[self setImage:[CFCHStyleSheet imageForTickButtonChecked] forState:UIControlStateNormal];
[self setImage:[CFCHStyleSheet imageForTickButtonChecked] forState:UIControlStateSelected];
[self setImage:[CFCHStyleSheet imageForTickButtonCheckedDisabled] forState:UIControlStateDisabled];
}
else
{
[self setImage:[CFCHStyleSheet imageForTickButtonUnchecked] forState:UIControlStateNormal];
[self setImage:[CFCHStyleSheet imageForTickButtonUnchecked] forState:UIControlStateSelected];
[self setImage:[CFCHStyleSheet imageForTickButtonUncheckedDisabled] forState:UIControlStateDisabled];
}
[super setSelected:selected];
}

Resources