Make UIButton both image and text tappable - ios

I have a UIButton with text and an image that looks like this:
But when I click the button it goes like this (just the image is selected instead of both the image and the text, I want button text also be selected.
How can I fix it?

Yes, you can set this color in your xib (interface builder) also, just select your button and inside State config select Highlighted and then set the textColor for that state. Check image for reference.

Objective-C
Use [UIButton setTitleColor:forState:] API
[yourButton setTitleColor:[UIColor grayColor] forState: UIControlStateHighlighted];
Swift
yourButton.setTitleColor(UIColor.grayColor(), forState: .Highlighted)

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];

How to disable UIButton Tint Color?

I know my case may be rare but how do you disable the UIButton tint colour in this case?
I have a customised UIButton which has attributedTitle to help display the button pattern in different colour and alpha.
In my customised button .m file I have set something like this
[self setBackgroundImage:[self imageWithColor:[UIColor grayColor]] forState:UIControlStateSelected];
which will make the background colour to gray when the button is selected
However the real result looks like this:
Some how the text colour gets turned into white which I think is because of the tint effect on UIButtons.
Is that possible for me to have the background as grey while the text still remain the colour as set in the attributed title on selected state of the button?
Thanks
yourbutton = [UIButton buttonWithType:UIButtonTypeCustom];
(or)
If u placed button in storyboard....Choose button type as custom instead of system.
You can override setImage:forState: in UIButton subclass and change rendering mode to .alwaysOriginal.
override func setImage(_ image: UIImage?, for state: UIControlState) {
let newImage = image?.withRenderingMode(.alwaysOriginal)
super.setImage(newImage, for: state)
}
Simple, just head to the image in your assets, and set its rendering mode to "Original Image", check image below:
Follow this steps to get result:
First set UITabBar background color to clear
Now put this line in viewDidLoad method of the first page:
[[UITabBar appearance] setTintColor:SETYOURCOLOR];
Hope it will help you.

UIButton image goes grey on press

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)

Set image of uiButton in custom table cell

I have a uitbutton within a custom table cell. I am trying to set the buttons image with
[cell.thumbImage setImage:[UIImage imageNamed: #"full_breakfast.jpg"] forState:UIControlStateNormal];
It is displaying a blue button instead of the image like so:
Am I doing this wrong? When i remove the uibutton setImage it returns to the normal button. This SHOULD be fairly simple so sorry if it is.
In iOS7 there is new button type called UIButtonTypeSystem NS_ENUM_AVAILABLE_IOS(7_0), // standard system button
Check your .xib file and change button type to Custom, or programatically you can do this:
[UIButton buttonWithType:UIButtonTypeSystem];

is it possible to update UIButton title/text programmatically?

I have a UIButton, that when pressed, brings up a new view where the user can change some settings. When the view is dismissed, I'd like to update the title/text of the UIButton to reflect the new state. I'm calling:
[myButton setTitle: #"myTitle" forState: UIControlStateNormal];
[myButton setTitle: #"myTitle" forState: UIControlStateApplication];
[myButton setTitle: #"myTitle" forState: UIControlStateHighlighted];
[myButton setTitle: #"myTitle" forState: UIControlStateReserved];
[myButton setTitle: #"myTitle" forState: UIControlStateSelected];
[myButton setTitle: #"myTitle" forState: UIControlStateDisabled];
But it never seems to change from the original text/title as specified in IB.
I solved the problem just setting the title parameter for UIControlStateNormal, and it automatically works on the other states. The problem seems to be when you set another UIControlState.
[myButton setTitle: #"myTitle" forState: UIControlStateNormal];
Do you have the button specified as an IBOutlet in your view controller class, and is it connected properly as an outlet in Interface Builder (ctrl drag from new referencing outlet to file owner and select your UIButton object)? That's usually the problem I have when I see these symptoms.
Edit: While it's not the case here, something like this can also happen if you set an attributed title to the button, then you try to change the title and not the attributed title.
As of Swift 4:
button.setTitle("Click", for: .normal)
I discovered another problem. It may be a bug introduced in iOS 5, but I thought I'd point it out for anyone else who encounters it.
If you don't set any default text for the button in the XIB, no text will ever appear if you set it programmatically. And if you do set text in the XIB, any text you subsequently assign to the button programmatically will be truncated to the size of the default text.
And finally, if you're showing the view with your button and then invoke another view (like an ActionSheet) and then dismiss it, the text that you assigned to the button programmatically will be erased and the button caption will return to whatever you set up in the XIB.
Even though Caffeine Coma's issue was resolved, I would like to offer another potential cause for the title not showing up on a UIButton.
If you set an image for the UIButton using
- (void)setImage:(UIImage *)image forState:(UIControlState)state
It can cover the title. I found this out the hard way and imagine some of you end up reading this page for the same reason.
Use this method instead
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state
for the button image and the title will not be affected.
I tested this with programmatically created buttons and buttons created in a .xib
for swift :
button.setTitle("Swift", forState: UIControlState.Normal)
One more possible cause is this:
If you attempt to set the button's title in the (id)initWithNibName: ... method, then you're button property will still be nil. It hasn't yet been assigned to the UIButton.
You must be sure that you're setting your buttons in a method like (void)viewWillLoad or (void)viewWillAppear, but you probably don't want to set them as late as (void)viewDidAppear.
Turns out the docs tell you the answer! The UIButton will ignore the title change if it already has an Attributed String to use (with seems to be the default you get when using Xcode interface builder).
I used the following:
[self.loginButton
setAttributedTitle:[[NSAttributedString alloc] initWithString:#"Error !!!" attributes:nil]
forState:UIControlStateDisabled];
[self.loginButton setEnabled:NO];
Sometimes it can get really complicated. The easy way is to "refresh" the button view!
//Do stuff to your button here. For example:
[mybutton setEnabled:YES];
//Refresh it to new state.
[mybutton setNeedsDisplay];
I kept having problems with this, the only solution was to add an image and label as subviews to the uibutton. Then I discovered that the main problem was that I was using a UIButton with title: Attributed. When I changed it to Plain, just setting the titleLabel.text did the trick!
#funroll is absolutely right. Here you can see what you will need Make sure function runs on main thread only. If you do not want deal with threads you can do like this for example: create NSUserDefaults and in ViewDidLoad cheking condition was pressed button in another View or not (in another View set in NSUserDefaults needed information) and depending on the conditions set needed title for your UIButton, so [yourButton setTitle: #"Title" forState: UIControlStateNormal];
Make sure you're on the main thread.
If not, it will still save the button text. It will be there when you inspect the object in the debugger. But it won't actually update the view.

Resources