UIButton with background image: title text randomly does not appear - uibutton

I am setting the background image on a UIButton which has title text. This works fine, except that about 5% of the time, rarely and non-deterministically, with the same code, the text does not appear.
In my UIButton subclass:
[self setBackgroundImage:normalImage forState:UIControlStateNormal];
// Also set a background image for all other states.
In a UIButton category, I have this convenience method for setting the title:
- (void)setNormalTitle:(NSString *)title {
[self setTitle:title forState:UIControlStateNormal];
[self setTitle:title forState:UIControlStateSelected];
[self setTitle:title forState:UIControlStateHighlighted];
[self setTitle:title forState:UIControlStateSelected | UIControlStateHighlighted];
}
I'm not finding this issue having been encountered by anyone. Any ideas? I can always create a custom UIView which contains the button and draws text on top using a UILabel, but I wonder if there's a known issue I'm encountering here.
Update: I seem to have worked around the issue by setting the title asynchronously:
_tabCell = loadTopNibObject(#"MYTabSmall3HeaderCell");
dispatch_async(dispatch_get_main_queue(), ^{
_tabCell.tab0Button.normalTitle = #"Option 1";
_tabCell.tab1Button.normalTitle = #"Option 2";
_tabCell.tab2Button.normalTitle = #"Option 3";
});
Update 2: Nope, the above doesn't work. I've breakpointed and printed out the empty button's text, which reports the correct string even though the button appears blank. I've also tried running setNeedsDisplay: when the button is touched, to no avail. Also tried re-setting the button text to some specific string (e.g. #"test") on touch but this doesn't kick in any visible letting.

Related

UIButton in tvOS: focused state interferes with text

Since there's no UISwitch in tvOS, I'm using a UIButton to implement a simple On/Off toggle. I've set the button title text for UIControlStateNormal and UIControlStateSelected to indicate the button's on/off state, but the new UIControlStateFocused now interferes with this by setting the title text to be the same as the default state whenever the button is in focus. This means that when the button is "On", whenever it gets focus its title changes to "Off".
The only way I've found to get around it is to explicitly set the title for the focused state in the button handler as shown below.
- (void)viewDidLoad
{
[super viewDidLoad];
// in reality these strings are setup in the storyboard
[self.enabledButton setTitle:#"Off" forState:UIControlStateNormal];
[self.enabledButton setTitle:#"On" forState:UIControlStateSelected];
// ensure the text shows up in focused state
[self.enabledButton setTitleColor:[UIColor blackColor] forState:UIControlStateFocused];
}
- (IBAction)toggleStateForEnabledButton:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = !button.selected;
if (button.selected)
{
[button setTitle:[button titleForState:UIControlStateSelected] forState:UIControlStateFocused];
}
else
{
[button setTitle:[button titleForState:UIControlStateNormal] forState:UIControlStateFocused];
}
}
This feels very hackish to me, esp. since there might be lot of this going on in UISwitch's absence. Is there a better way?
Have you tried setting a title for UIControlStateFocused | UIControlStateSelected ? It's a bit field, so should be possible to combine them.

UIButton settitle dynamically change

I have a uibutton and I am changing its title to a data that I am receiving from webservice I have printed the uibutton current tile and the title I want to show but its not changing the button title
NSString *str = [NSString stringWithFormat:#"%#",[[status objectForKey:#"detail"] valueForKey:#"goalDetailText"]];
[goalButton setTitle:str forState:UIControlStateSelected];
NSLog(#"title is %# and value is %#",goalButton.currentTitle,str); [goalButton setTitle:str forState:UIControlStateSelected];
console is
2013-11-25 12:13:04.666 = sdad [3389:1003] title is Loading ... and value is Learn and practise how to minimize "emotional eating"
but the problem is the uibutton title is taking time to change the title like a loong time, but I have checked the value from webservice is not null and its printing absolutely fine but the settitle is taking too much time. my project is on IOS7.
If your button state changed to normal, after you tapped up inside, you need to use UIControlStateNormal status for title:
[goalButton setTitle:str forState:UIControlStateNormal];

How do I change a UIButton state programatically?

the .selected and .highlighted properties don't cut it, because for some reason the button looks even more greyed out (darker shade of the non-highlighted image) when highlighted and selected are set to YES.
I need to make my button go off, just as if the user made it go off.
How do I do that?
I now think I understand what you mean. I put a image in my UIButton and tried to change the state of the button on touch down.
- (IBAction)touchDown:(id)sender {
[(UIButton *)sender setHighlighted:FALSE];
[(UIButton *)sender setSelected:FALSE];
}
I noticed that the image does not become darker until you move your finger. If you connect an action to "touch drag inside" and check .highlighted you should see that it has turned TRUE again. You could set it back to FALSE:
- (IBAction)touchMove:(id)sender
{
[(UIButton *)sender setSelected:FALSE];
}
However
If you're only looking for a way to stop the image from turning grey when the user presses it, do this:
button.adjustsImageWhenHighlighted = FALSE;
Setting an image for UIControlStateHighlighted would also remove the greying.
UIImage *image = [UIImage imageNamed:#"img"];
[button setImage:image forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateHighlighted];
If by "go off" you mean you want to disable the button, you can use:
[myButton setEnabled:NO];

How to move an image with a button?

I have an image(clubcow.png) that is passed from an nsarray string to make a picture. Then facedowncow represents the picture. I was wondering how to make a button that will move facedowncow to position (100,100) when button is tapped. Any tips will be appreciated. Also, there is more to this code, I just posted the important parts to give an idea on what is going on.
cardKeys = [[NSArray alloc] initWithObjects:#"clubcow", nil];
currentName = [NSMutableString stringWithFormat:#"%#.png", [cowsShuffled objectAtIndex:currentcow]];
faceDowncow = (UIImageView *)[self.view viewWithTag:1];
faceDowncow.userInteractionEnabled = YES;
I would start by creating a UIButton and adding it to your view controller's view.
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(0, 0, 100, 20);
[button setTitle:#"Tap Me" forState:UIControlStateNormal];
[button addTarget:self action:#selector(animateImage:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
Then, link this button to a function that will animate your faceDowncow object. You could add your faceDowncow as a property of the view controller so the following function can easily reference it:
- (void)animateImage:(UIButton *)sender {
[UIView animateWithDuration:0.2
animations:^{
// change origin of frame
faceDowncow.frame = CGRectMake(100, 100, faceDowncow.frame.size.width, faceDowncow.frame.size.height);
} completion:^(BOOL finished){
// do something after animation
}];
}
First of all, it looks like this code is from a view controller subclass, and the cow is a subview. In that case, you should probably have a property for it rather than obtaining it by its tag all the time. If it's instantiated in a storyboard scene/nib then you can hook up an outlet to a property/ivar in your subclass fairly easily.
The easiest way to do what you want is to create the button and use target action so that when it is tapped, it calls a method in your view controller. In the method body, obtain a reference to your cow and set it's frame property, like so:
[faceDowncow setFrame: CGRectMake(100,100,faceDowncow.bounds.size.width,faceDowncow.bounds.size.height)];
If you don't know how target action works, I suggest reading Apple's documentation on the matter. It's as simple as getting a button, calling one method to tell it what events should make a certain method get called, and then implementing that method.

Change Round Rect Button background color on StateHighlighted

I'm trying to change the background color of a button when it's selected and don't want to use an image.
[mBtn setBackgroundColor:[UIColor grayColor] forState:UIControlStateHighlighted];
Any thoughts?
I'm replying to this old thread because it pops up consistently in searches for a solution to this problem and I have seen no solution elsewhere. It is truly annoying that setTintColor only applies to the highlighted state of a UIButton. Six months ago, it was equally annoying that it applied only to iOS 5, but that will hopefully be less of an issue going forward. With that in mind, I've drawn upon and combined a number of community suggestions to composite a general purpose solution to tinting a group of buttons in their normal state.
The method below accepts an NSArray of UIButtons and a set of color specifications as input. It applies the color specifications to one button using setTintColor, renders the result to a UIImage, and applies that image as the background image of the entire set of buttons. This avoids the need to create discrete image files for button colors. Also, it does so using a stretchable image so that it may work with a collection of buttons of different sizes (though note that it assumes the default corner rounding factors of UIButton). I hope you'll find it useful for iOS 5 targets.
- (void) setColorOfButtons:(NSArray*)buttons red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha {
if (buttons.count == 0) {
return;
}
// get the first button
NSEnumerator* buttonEnum = [buttons objectEnumerator];
UIButton* button = (UIButton*)[buttonEnum nextObject];
// set the button's highlight color
[button setTintColor:[UIColor colorWithRed:red/255.9999f green:green/255.9999f blue:blue/255.9999f alpha:alpha]];
// clear any existing background image
[button setBackgroundImage:nil forState:UIControlStateNormal];
// place the button into highlighted state with no title
BOOL wasHighlighted = button.highlighted;
NSString* savedTitle = [button titleForState:UIControlStateNormal];
[button setTitle:nil forState:UIControlStateNormal];
[button setHighlighted:YES];
// render the highlighted state of the button into an image
UIGraphicsBeginImageContext(button.layer.frame.size);
CGContextRef graphicsContext = UIGraphicsGetCurrentContext();
[button.layer renderInContext:graphicsContext];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIImage* stretchableImage = [image stretchableImageWithLeftCapWidth:12 topCapHeight:0];
UIGraphicsEndImageContext();
// restore the button's state and title
[button setHighlighted:wasHighlighted];
[button setTitle:savedTitle forState:UIControlStateNormal];
// set background image of all buttons
do {
[button setBackgroundImage:stretchableImage forState:UIControlStateNormal];
} while (button = (UIButton*)[buttonEnum nextObject]);
}
[mBtn setTintColor:[UIColor grayColor]];
This only effects the highlighted state, so I believe that this is what you're looking for.
You can also set it from Interface Builder, from the Highlight Tint drop-down menu.
Just for people that will land here like I did when searching for changing background colors for highlighted state...
I ended up with an UIButton subclass that has a property for backgroundHighlightColor and tracks highlighting through KVO. Here's the link to GitHub: SOHighlightButton
You should be able to adapt it to any other scenario if you need more / other properties ot the UIButton to change if highlighted.
There is no method like this, setBackgroundColor: forState:
Check documentation. you need to use image.