is it possible to update UIButton title/text programmatically? - ios

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.

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

Make UIButton both image and text tappable

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)

SetTitle Doesn't Change the Text of a UIButton

Pretty straight forward; just trying to change the display name of my button from "Button" to "a." But the setTitle method doesn't seem to do anything. I played around with the UIState, and that didn't seem to change much.
Do I maybe need to synthesize anything?
[Button1 setTitle:#"a" forState:UIControlStateNormal];
EDIT:
I did an NSLog, and the button is showing as NULL, which I've been told means it isn't connected properly. But I double-checked my Connections Inspector, looked at the H file, and everything seems to link up fine. (http://imgur.com/EFsp51U) What am I missing?
If you have created your button in Interface Builder, then go there and change its type to custom.
And also check if you have connected your IBOutlet correctly.
I went digging through my code, and in my viewDidLoad method, I had the following:
Button1 = NO;
I think I was trying to type out "selected" but got distracted and didn't come back to it, and so was inadvertently turning my own button off. The correct code is:
self.Button1.selected=NO;
[self.Button1 setTitle:#"a" forState:UIControlStateNormal];
Make sure Button1 is not nil
Make sure Button1.hidden = NO;
I'm not sure that the problem is about thread but you may want to try to set the title on main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[Button1 setTitle:#"a" forState:UIControlStateNormal];
});
Your code is perfectly valid. But just to make sure everything is ok, add following extra line,
Button1.selected = NO;
[Button1 setTitle:#"a" forState:UIControlStateNormal];
Make sure you have synthesized your Button.
//this assumes you have a button "myButton" declared in your interface file
#implementation
#synthesize myButton;
-(void) myMethod{
[myButton setTitle:#"The new Title" forState:UIControlStateNormal];
}
#end
You should have your button connected through IB outlets to your .h file or create the button entirely through code.
Also it is good practice to not have variable names beginning with a capital letter.
If you haven't explicitly synthesized it then you should be calling either
[_Button1 setTitle:#"a" forState:UIControlStateNormal];
or
[self.Button1 setTitle:#"a" forState:UIControlStateNormal];
Do the following:
Do
NSLog(#"%#", Button1);
and check that it's not nil.
Check that
NSLog(#"%d", btn.state);
should return 0.

How to set an invisible title on UIButton?

I'm working on an Ipad application, and i need to set a title on a 'UIButton', in order to could use :
-(void)MyMethod:(id)sender
{
UIButton *resultButton = (UIButton *)sender;
if ([resultButton.currentTitle isEqualToString:#"TitleName"])
{
...
}
}
But when I use this sort of code :
[MyUibutton setTitle:#"TitleName" forState:UIControlStateNormal];
It appears "TitleName" behind the image of the 'UIButton'...
So, is it possible to fix it ?
Thanks !
Don't use the button title, it's for display, not a flag. Instead use a tag or objc_setAssociatedObject Or store the button in a dictionary and compare.
theButton.titleLabel.alpha = 0;
If you set the image of the button, it will be at the top of the button, so the button's title won't be visible. Set the button's background and it will solve your problem !
[yourbutton setBackgroundImage:YOURIMAGE forState:UIControlStateNormal];
You can do [button setTitle:title forState:UIControlStateDisabled]; as long as you know you are not ever going to disable the button. Other than that, using the tag property is probably the easiest.

How to disable the highlight control state of a UIButton?

I've got a UIButton that, when selected, shouldn't change state when being touched.
The default behaviour is for it to be in UIControlStateHighlighted while being touched, and this is making me angry.
Suggestions?
Your button must have its buttonType set to Custom.
In IB you can uncheck "Highlight adjusts image".
Programmatically you can use theButton.adjustsImageWhenHighlighted = NO;
Similar options are available for the "disabled" state as well.
In addition to above answer of unchecking "highlight adjusts image" in IB, make sure that button type is set CUSTOM.
This will work for you:
[button setBackgroundImage:[UIImage imageNamed:#"button_image"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"button_image_selected"] forState:UIControlStateSelected];
[button setBackgroundImage:[UIImage imageNamed:#"button_image_selected"] forState:UIControlStateSelected | UIControlStateHighlighted];
3rd line is the trick here...
This works the same for setting image/backgroundImage
adjustsImageWhenHighlighted = NO;
button.adjustsImageWhenDisabled = NO;
is equally useful for having your own appearance of a disabled button.
Depending on what changes from the default to the highlighted state of the button, you can call a couple of methods to set them to what you need. So if the image changes you can do
[myButton setImage:[myButton imageForState:UIControlStateNormal] forState:UIControlStateHighlighted];
If the text changes you can do
[myButton setTitle:[myButton titleForState:UIControlStateNormal] forState:UIControlStateHighlighted];
other similar functions:
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state
- (void)setTitleShadowColor:(UIColor *)color forState:(UIControlState)state
For Swifty Developer -
yourButton.adjustsImageWhenHighlighted = false
Swift 3+
button.adjustsImageWhenHighlighted = false
button.adjustsImageWhenDisabled = false
OK here's an easy solution if this works for you, after a week of banging my head on this it finally occurred to me to just set highlighted=NO for the 1st line of the IBAction method for the TouchUpInside or TouchDown, or whatever works. For me it was fine on the TouchUpInside.
-(IBAction)selfDismiss:(id)sender {
self.btnImage.highlighted = NO;
NSLog(#"selfDismiss");
etc, etc, etc.
}
make your button Type - "Custom"
and Uncheck - Highlighted Adjust image and
you are done.
just two things:
UIButton *btnTransparentComponent = [UIButton buttonWithType:UIButtonTypeCustom];
btnTransparentComponent.adjustsImageWhenHighlighted = NO;
I had a similar issue and found that "unchecking" Clears Graphic Content in interface builder fixed my issue
After the introduction of Style, you have to set the style to Default in IB along with setting the type to Custom to be able to disable the highlighting effect completely. Otherwise your button text will keep highlighting.
*Setting the Style to Default resets the text color to white.
avoid to set UIButton's Line Break to Clip, use instead the standard Truncate Middle

Resources