I need 2 different images for highlighted state for an UIButton.
I've these lines of code:
- (IBAction)buttonPressed:(id)sender
{
UIImage *followImageHighlighted = [UIImage imageNamed:#"follow-hilite.png"];
UIImage *unfollowImageHighlighted = [UIImage imageNamed:#"unfollow-hilite.png"];
if ([sender isSelected]) {
// set this image for the next time the button will pressed
[sender setImage:unfollowImageHighlighted forState:UIControlStateHighlighted];
} else {
// set this image for the next time the button will pressed
[sender setImage:followImageHighlighted forState:UIControlStateHighlighted];
}
}
- (void)viewDidLoad
{
// ...
UIImage *followImage = [UIImage imageNamed:#"follow.png"];
UIImage *unfollowImage = [UIImage imageNamed:#"unfollow.png"];
[self.followButton setImage:followImage forState:UIControlStateNormal];
[self.followButton setImage:unfollowImage forState:UIControlStateSelected];
}
The problem is that every time I press the button I see the highlighted image follow-hilite.png.
Can't I change the highlighted image for a button on the road?
I think this is a bad limitation because when the button is selected (thus, "Following") and an user press it, he see the default image, then when it touch up the image is that for selected state and when the network operation is completed then the button image switch correctly to the selected one.
Ideas?
EDIT
- (IBAction)followButtonTapped:(id)sender
{
BOOL isFollowed = [sender isSelected];
NSString *urlString = isFollowed ? kUnfollowURL : kFollowURL;
// operation [...]
[self.followButton setSelected:(isFollowed) ? NO : YES];
self.user.followed = !isFollowed;
}
I explain better the problem:
button in default state: black text on white background
button in selected state: white text on black background
If the target user is not followed, the button is in default state and if I try to press it I see the correct highlighted image.
BUT if the target user is followed and the button is in selected state, if I try to press it (and hold the finger) I see the button with black text on white background. This is very ugly and this is my problem.
The IBAction is an awkward (at best, or impossible) place to configure the control. There must be some condition in your app that triggers the requirement for the different highlighted image. Configure the button when you detect that condition.
Use the "pressed" callback for taking whatever action the app is supposed to take on the press.
I've solved with:
[myButton setImage:imageSelectedHover forState:(UIControlStateSelected | UIControlStateHighlighted)];
Glad it works. You solved it by updating the application condition: self.user.followed. Now, to make it really right, try this:
- (IBAction)followButtonTapped:(id)sender
{
NSString *urlString = self.user.followed? kUnfollowURL : kFollowURL;
// operation [...]
self.user.followed = !self.user.followed;
}
The state of your model is what matters here. The selected state of the button is more like a bool that was lying around where you are keeping a copy of the real following state.
I think you need to cast sender to UIButton* before you try to modify anything important and work out your variables, because sender does not include a method or property called -isSelected. Try this instead:
- (IBAction)buttonPressed:(id)sender
{
UIImage *followImageHighlighted = [UIImage imageNamed:#"follow-hilite.png"];
UIImage *unfollowImageHighlighted = [UIImage imageNamed:#"unfollow-hilite.png"];
if ([self isSelected]) {
// set this image for the next time the button will pressed
[(UIButton*)sender setImage:unfollowImageHighlighted forState:UIControlStateHighlighted];
} else {
// set this image for the next time the button will pressed
[(UIButton*)sender setImage:followImageHighlighted forState:UIControlStateHighlighted];
}
[self isSelected] = ![self isSelected];
}
Related
I have a number of UIButtons in a vertical Line. All buttons have images btnImage.png btnImage_selected.png.
The Actions are set as UIEventTouchUpInside. Now i have added selected To HighLighted state of teh button.
When I press on button it shows the selected version but when i lift the finger of , it changes back to normal.
How can I make code so when the button is pressed it changes it state and stick to selected image and when another button is pressed it automatically changes back to normal state where as other button normal state is changed to selected one.
Setting the image for the Highlighted state will only set the image when it's highlighted. You'll need to set the image for all states, when the button is pressed.
Hook up all IBActions for each button to buttonPressed
#property (nonatomic, strong) NSArray *arrayOfButtons;
- (void)viewDidLoad
{
self.arrayOfButtons = [NSArray arrayWithObjects:button1, button2, button3, button4, button5, button6, button7, button8, button9, button10, nil];
}
- (IBAction)buttonPressed:(id)sender
{
for (UIButton *button in self.arrayOfButtons)
{
if (! [button isEqual:sender])
{
[button setImage:[UIImage imageNamed:#"btnImage.png"] forState:UIControlStateNormal];
} else
{
[button setImage:[UIImage imageNamed:#"btnImage_selected.png"] forState:UIControlStateNormal];
}
}
}
If you make the buttons in a xib you can you an IBOutletCollection to hold a reference to all the buttons. Or you can add a property that holds all the buttons.
- (NSArray *)allButtons
{
return _allButtons = _allButtons ?: #[
button01,
button02,
button03,
button04,
button05,
button06,
button07,
button08,
button09,
button10,
];
}
Now you need an method that will set one button to active
- (void)setActiveButton:(UIButton *)activeButton
{
for (UIButton *button in self.allButtons) {
button.enabled = button == activeButton;
}
}
I'm working on a form for the iphone and I would like a female/male button choice. The buttons originally have an M and an F written on them and when you choose one, an image flips over. I managed to display the images when the buttons are pressed. The problem I was having is that they were able to both be displayed at the same time but when one is enabled the other image should disappear. I've tried to correct it and now the program crashes.
implementation file:
-(IBAction) setCheckBox2: (id) sender
{
UIImage *selected = [UIImage imageNamed:#"female.tiff"];
// UIImage *notSelected = [UIImage imageNamed:#"male.tiff"];
if (sender == selected)
{
[sender setImage:selected];
}
else
{
[sender setImage:NO];
}
Then I was going to create another function for the male image being selected. Any suggestions?
Thanks!
You are testing that sender == selected hence implying that sender is of type UIImage, and then sending setImage: to sender... with itself as parameter.
This doen't make sense. I think what you were trying to do must look something like:
-(IBAction) setCheckBox2: (UIImageView *) sender
{
UIImage *selected = [UIImage imageNamed:#"female.tiff"];
UIImage *notSelected = [UIImage imageNamed:#"male.tiff"];
if (sender.image == selected)
{
[sender setImage:notSelected];
}
else
{
[sender setImage:selected];
}
}
Why not you are using default(for not selected) and selected(for selected) property for these two state. The advantage to do this is you will not have to write a bunch of code. OK set selected image and default image.
Take a global variable of UIButton for currentSelectedButton.
connect both the UIButton with single IBActionMethod named genderButtonClicked(or you want).
Now
-(IBAction)genderButtonClicked:(UIButton)sender
{
if(currentSelectedButton)
[currentSelectedButton setSelected:FALSE];
currentSelectedButton = sender;
[currentSelectedButton setSelected:TRUE];
}
I Think this will solve your problem
I am trying to check the condition of checkboxes.For making checkbox i use button.I changed there sizes and provide image as checked or unchecked on their click method.Now i have two checkboxes.Now i am trying to store array value on the bases of checkbox clicked.I mean that when i click check box the specific value of the array store in the string and if i uncheck then the value of string set to null.
For that i did:
-(void) checkBoxIsAcitiveClicked
{
NSLog(#"check box button clicked");
if( [UIImage imageNamed:#"checkbox_ticked.png"])
{
isActiveStr=[arrayPickerData objectAtIndex:17];
NSLog(#" is active value is %# is fetched succesfuly",isActiveStr);
[CommonVar setIsActiveStrData:isActiveStr];
NSLog(#" is active value send to cmmon class %# sent succesfuly",isActiveStr);
}
else
{
NSLog(#"no vlaue send");
isActiveStr=nil;
[CommonVar setIsActiveStrData:isActiveStr];
NSLog(#" is active value send to cmmon class %# sent succesfuly",isActiveStr);
}
}
1)CommonVar is my common class
2)setIsActiveStrData is my class method in commonvar class
3)isActiveStr is my NSMutableString.
4)arrayPickerData is my NSMutableArray
Now i dont know how to check the condition that button image is checked.png or unchecked.png
Please help me
Thank You
UIImage *uncheckmark = [UIImage imageNamed:#"checkbox_unticked.png"]; // Unticked image
[checkbutton setImage:uncheckmark forState:UIControlStateNormal];
UIImage *checkmark = [UIImage imageNamed:#"checkbox_ticked.png"]; // ticked image
[checkbutton setImage:checkmark forState:UIControlStateSelected];
[checkbutton addTarget:self action:#selector(selectedTouched:)
forControlEvents:UIControlEventTouchUpInside];
-(IBAction)selectedTouched:(id)sender{
UIButton *aButton = (UIButton*)sender;
// to check/unchecked and Implement your logic here
(aButton.selected) ? NSLog(#"Checked") : NSLog(#"Un-Checked");
[aButton setSelected:!(aButton.selected)];
}
Sorry if this is a basic question, I can't find a definitive answer.
I have set up 4 buttons:
// Add the normal and selected state for each button
UIImage *buttonImage = [UIImage imageNamed:[NSString stringWithFormat:#"HotspotNumber2-%i.png",(hotspotID +1)]];
[hotspotButton setImage:buttonImage forState:UIControlStateNormal];
UIImage *buttonImageSelected = [UIImage imageNamed:[NSString stringWithFormat:#"HotspotNumber2-%is.png",(hotspotID +1)]];
[hotspotButton setImage:buttonImageSelected forState:UIControlStateSelected];
[hotspotButton setImage:buttonImageSelected forState:UIControlStateHighlighted];
[hotspotButton addTarget:self action:#selector(hotspotTouch:) forControlEvents:UIControlEventTouchDown];
And I trap the touch events in the method:
// Called when a hotspot is touched
-(void)hotspotTouch:(id)sender{
// Deselect the hotspot currently selected
if (selectedHotspot) [selectedHotspot setSelected:NO];
selectedHotspot = (UIButton *)sender;
[selectedHotspot setSelected:YES];
// Get dictionary of hot spot that is pressed
NSDictionary *hotspot = [hotspots objectAtIndex:[selectedHotspot tag]];
NSString *imageFileName = [hotspot objectForKey:ksHotspotItemKey];
if ([imageFileName length] > 0) currentImageView.image = [UIImage imageNamed:imageFileName];
}
}
The problem I have is that the highlighted image for the button does not display until the user releases their finger, which is a noticeable delay. I have seen others solve similar issues by changing the background image instead of the button state or performing a selector after a delay so the run loop gets chance to end. Both methods seem like hacks to me and would be grateful if someone could explain what is happening here and what the most robust way of achieving the effect that as soon as the user touches down on the button it changes to its highlighted state.
Thanks in advance,
Dave
Have found a work around. I have created one method for TouchDown and one for TouchUpInside and TouchUpOutside. The TouchDown simply deselects the button if it is already selected and changes my view's image. The TouchUp event sets the selected property of the button. As both the highlighted and selected images are the same the net effect is that the button changes as soon as the button is touched and remains that way after the touch up events. Code is here:
// Called when a hotspot is touched down
-(void)hotspotTouchDown:(id)sender{
// Deselect the hotspot currently selected if it exists
if (selectedHotspot) [selectedHotspot setSelected:NO];
// Get dictionary of hot spot that is pressed
NSDictionary *hotspot = [hotspots objectAtIndex:[sender tag]];
// If the class of the hotspot is 'self' then replace the current image with a new one given in the hotspot data
if ([[hotspot objectForKey:ksHotspotClassKey] isEqualToString:ksHotspotClassSelf]) {
NSString *imageFileName = [hotspot objectForKey:ksHotspotItemKey];
if ([imageFileName length] > 0) currentImageView.image = [UIImage imageNamed:imageFileName];
}
}
// Called when a hotspot is touched up
-(void)hotspotTouchUp:(id)sender{
// Set the selected property of the button
selectedHotspot = (UIButton *)sender;
[selectedHotspot setSelected:YES];
}
I have two round rect buttons. I have implemented its touch up inside action. It works fine but when my click second button just after clicking the first button, my first click has no effect. This is happening with both the buttons. I am actually trying to change background image of buttons on each click to get the effect of check box (checking/unchecking). Below is the code for for one of the buttons:
-(IBAction) checkButton2: (id) sender
{
self.checkButton2 = sender;
if ( isCheck == NO)
{
[self.checkButton2 setImage: [UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
isCheck = YES;
}
else
{
[self.checkButton2 setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
isCheck = NO;;
}
}
This is solved. Actually I was using isCheck BOOL type variable for two actions(One is given above) for two buttons and both actions were setting this variable separately which shows deviation from expected behavior.