UIButton causing a crash - ios

I'm having a bit of a problem here. I've created a button and want it to change it's backgroundImage on being clicked. It's not working and I get a SIGABRT error.
The code is as follows:
- (IBAction)indicatedButton:(id)sender
{
if ([sender isSelected])
{
[sender setBackgroundImage:[UIImage imageNamed:#"completeTickBox.png"]];
}
else
{
[sender setBackgroundImage:[UIImage imageNamed:#"blankTickBox.png"]];
}
}

I think you want:
[sender setBackgroundImage:[UIImage ....] forState:UIControlStateNormal];
Here's the relevant Apple documentation on the method: https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/occ/instm/UIButton/setBackgroundImage:forState:
So in your case, it would be:
- (IBAction)indicatedButton:(id)sender
{
if ([sender isSelected])
{
[sender setBackgroundImage:[UIImage imageNamed:#"completeTickBox.png"] forState:UIControlStateNormal];
}
else
{
[sender setBackgroundImage:[UIImage imageNamed:#"blankTickBox.png"] forState:UIControlStateNormal];
}
}
Assuming here that "sender" is actually a UIButton.

First verify you're getting a UIButton
-(IBAction indicatedButton:(id)sender
{
if ([sender isKindOfClass:[UIButton class]])
{
}
}
Convention tip: best practice for properties of an object is to use dot notation (isSelected is a BOOL property of UIButton)
-(IBAction indicatedButton:(id)sender
{
if ([sender isKindOfClass:[UIButton class]])
{
if (sender.isSelected)
{
}
}
}
If you're just using a regular button, but what you want is a "toggle" button (it's one image, or a different image), then you need to set the selected state property for the button, so that it -knows- it's selected after it's been touched (and vice versa if it isn't)
-(IBAction indicatedButton:(id)sender
{
if ([sender isKindOfClass:[UIButton class]])
{
if (sender.isSelected)
{
[sender setSelected:NO]; // if we were selected, we won't be now
UIImage *buttonImage = [UIImage imageNamed:#"completeTickBox.png"];
[sender setImage:buttonImage forState:UIControlStateNormal];
}
else if (!sender.isSelected)
{
[sender setSelected:YES]; // if we aren't selected, we will be now
UIImage *buttonImage = [UIImage imageNamed:#"blankTickBox.png"];
[sender setImage:buttonImage forState:UIControlStateNormal];
}
}
}
Instead of using introspection (the checking class types), if you know you want to work with a button, you could also change the button sender type from id to UIButton. You can do this without rewiring the button to the storyboard/nib
-(IBAction indicatedButton:(UIButton *)sender
{
if (sender.isSelected)
{
[sender setSelected:NO]; // if we were selected, we won't be now
UIImage *buttonImage = [UIImage imageNamed:#"completeTickBox.png"];
[sender setImage:buttonImage forState:UIControlStateNormal];
}
else if (!sender.isSelected)
{
[sender setSelected:YES]; // if we aren't selected, we will be now
UIImage *buttonImage = [UIImage imageNamed:#"blankTickBox.png"];
[sender setImage:buttonImage forState:UIControlStateNormal];
}
}

you have to cast sender as UIButton because sender is (id) and the object you want is UIButton so
put this line in your codeUIButton *btn=sender;
- (IBAction)indicatedButton:(id)sender
{
UIButton *btn= sender;
if ([btn isSelected])
{
[btn setBackgroundImage:[UIImage imageNamed:#"completeTickBox.png"] forState:UIControlStateNormal];
}
else
{
[btn setBackgroundImage:[UIImage imageNamed:#"blankTickBox.png"] forState:UIControlStateNormal];
}
}

Related

CheckBox issues with images

When I select the check box the second time it shows me the checked image, but the status is unchecked.
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
[CheckBox setBackgroundImage:[UIImage imageNamed:#"uncheck_checkbox.png"] forState:UIControlStateNormal];
}
- (IBAction)CheckBox:(id)sender {
if (CheckBox.selected == NO)
{
CheckBox.selected = YES;
[CheckBox setBackgroundImage:[UIImage imageNamed:#"checked_checkbox.png"] forState:UIControlStateNormal];
}
else
{
CheckBox.selected = NO;
[CheckBox setBackgroundImage:[UIImage imageNamed:#"uncheck_checkbox.png"] forState:UIControlStateSelected];
}
}
Your code is totally right just you replace UIControlStateSelected to UIControlStateNormal.
You need add normal image and selected images in IB itself (or in viewDidLoad) and toggle state for button in button action like below
- (IBAction)checkBoxAction:(UIButton *)sender {
sender.selected = !sender.selected;
}
if (sender.tag==0)
{
sender.tag = 1;
[sender setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
}
else
{
sender.tag=0;
[sender setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
}
When create button for check box you can save address this element on array after click on every button first access to all object on array seved and set image unckeck and this button clicked set image checked.
Or
When create button for check box set tag different for every button and when click on button you should be set image unckeck for every button use tag number and set image check for button clicked.
Also one thing,
Here you use CheckBox.selected = YES/NO;
So also you can write your code like:
- (void)viewDidLoad {
[super viewDidLoad];
CheckBox.selected = NO;
[CheckBox setBackgroundImage:[UIImage imageNamed:#"uncheck_checkbox.png"] forState:UIControlStateNormal];
[CheckBox setBackgroundImage:[UIImage imageNamed:#"checked_checkbox.png"] forState:UIControlStateSelected];
}
- (IBAction)CheckBox:(id)sender {
if (CheckBox.selected == NO)
{
CheckBox.selected = YES;
}
else
{
CheckBox.selected = NO;
}
}
- (IBAction)changeState:(id)sender {
UIButton *btn=(UIButton *)sender;
if (btn.selected == NO)
{
btn.selected = YES;
[btn setBackgroundImage:[UIImage imageNamed:#"checked_checkbox.png"] forState:UIControlStateNormal];
}
else
{
btn.selected = NO;
[btn setBackgroundImage:[UIImage imageNamed:#"uncheck_checkbox.png"] forState:UIControlStateNormal];
}
}
You should set boolean value to false in viewDidLoad and then in button click
- (IBAction)btnCheckBoxClick:(id)sender
{
if (isChecked)
{
[btnCheckBox setImage:[UIImage imageNamed:#"btncheckbox.png"] forState:UIControlStateNormal];
isChecked = false;
}
else
{
[btnCheckBox setImage:[UIImage imageNamed:#"btncheckbox_selected.png"] forState:UIControlStateNormal];
isChecked = true;
}
}

Set only single option in iOS

I have two custom round rect button and on this did tap event on image show.Like When we select gender there is only one option to select other automatically hide.but my gives when i touch first button than it select but when i touch second button no operation select.
My main moto is that i want to choose gender but in iOS no radio button use so i design custom and on click event set image.
calling api is a string type.
-(void)viewdidload
{
button = [UIButton buttonWithType:UIButtonTypeCustom];
callApi=#"MALE";//calling Api is a string type//
[button addTarget:self action:#selector(roundButtonDidTap:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)roundButtonDidTap:(UIButton*)tappedButton
{
if([callApi isEqualToString:#"FEMALE"]) {
UIImage *btnImage = [UIImage imageNamed:#"bullet.png"];
[button setImage:btnImage forState:UIControlStateNormal];
}
if ([callApi isEqualToString:#"MALE"]) {
UIImage *btnImage = [UIImage imageNamed:#"bullet.png"];
[button2 setImage:btnImage forState:UIControlStateSelected];
button.imageView.hidden=YES;
}
}
try this code:
-(IBAction)selectMale:(id) sender{ // MALE BUTTON
UIButton *RadioButton1 = (UIButton*)sender;
[self radiobuttonAction:RadioButton1];
}
-(void)radiobuttonAction:(UIButton *)Button
{
if(![Button isSelected])
{
[Button setSelected:YES];
[Button setImage:[UIImage imageNamed:#"radio_active.png"] forState:UIControlStateSelected];
gender = #"Male";
[btnFemale setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateSelected];
[btnFemale setSelected:NO];
}
else
{
[Button setSelected:NO];
[Button setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateNormal];
}
}
-(IBAction)selectFemale:(id) sender{
UIButton *RadioButton1 = (UIButton*)sender;
[self radiobuttonActionFemale:RadioButton1];
}
-(void)radiobuttonActionFemale:(UIButton *)Button
{
if(![Button isSelected])
{
[Button setSelected:YES];
[Button setImage:[UIImage imageNamed:#"radio_active.png"] forState:UIControlStateSelected];
gender = #"Female";
[btnMale setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateSelected];
[btnMale setSelected:NO];
}
else
{

Trouble using UiButton as toggle switch

I had luck with the below code using a UISwitch to toggle.
I need a UIButton to do the same. Not sure what I need to change to make that work?
Thanks for any help!
- (IBAction)switchNotes:(id)sender {
if([sender isOn]){
NSLog(#"Switch is ON");
for(UIButton *myButton in self.myButtonCollection) {
[myButton setTitleColor:[BT_color getColorFromHexString:#"#FFFF00"] forState:UIControlStateNormal];
[myButton setAlpha:1.0f];
}
} else{
NSLog(#"Switch is OFF");
for(UIButton *myButton in self.myButtonCollection) {
[myButton setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
[myButton setAlpha:1.0f];
}
}
}
- (IBAction)switchNotes:(id)sender
{
sender.selected = !sender.selected;
if(sender.selected)
{
NSLog(#"Switch is ON");
for(UIButton *myButton in self.myButtonCollection) {
[myButton setTitleColor:[BT_color getColorFromHexString:#"#FFFF00"] forState:UIControlStateNormal];
[myButton setAlpha:1.0f];
}
}
else
{
NSLog(#"Switch is OFF");
for(UIButton *myButton in self.myButtonCollection) {
[myButton setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
[myButton setAlpha:1.0f];
}
}
}
I believe your problem is that you are using the isOn property which is a property of UISwitch. According to this link iPhone UIButton with UISwitch functionality you should use the selected property of UIButton.

How to Deselect the image by clicking other button?

Hi in my application I ask the user to provide feedback. This could be to rate our server for example. They do this by clicking one of two buttons, good or bad. When they select an option the image for the button changes which is what I need it to do. The problem I have is that if they select good then select bad the good button needs to revert back to the 'un selected' option. As they cannot bother be 'selected'
My button code.
- (IBAction)gd:(id)sender {
UIButton *btn = (UIButton *)sender;
if ([sender isSelected]) {
[btn setBackgroundImage:[UIImage imageNamed:#"rd.png"] forState:UIControlStateNormal];
[sender setSelected:NO];
}
else{
[sender setBackgroundImage:[UIImage imageNamed:#"rd1.png"] forState:UIControlStateNormal];
[sender setSelected:YES];
}
}
- (IBAction)bd:(id)sender {
UIButton *btn1 = (UIButton *)sender;
if ([sender isSelected]) {
[btn1 setBackgroundImage:[UIImage imageNamed:#"rd.png"] forState:UIControlStateNormal];
[sender setSelected:NO];
}
else{
[sender setBackgroundImage:[UIImage imageNamed:#"rd1.png"] forState:UIControlStateNormal];
[sender setSelected:YES];
}
}
I have used the above but its not working like i want its showing like in the below image.
Please tell me show to resolve this one.
Create an outlet for both buttons and set the images for both states.
- (void)initButtons {
[gdBtn setBackgroundImage:[UIImage imageNamed:#"rd.png"] forState:UIControlStateNormal];
[gdBtn setBackgroundImage:[UIImage imageNamed:#"rd1.png"] forState:UIControlStateSelected];
[bdBtn setBackgroundImage:[UIImage imageNamed:#"rd.png"] forState:UIControlStateNormal];
[bdBtn setBackgroundImage:[UIImage imageNamed:#"rd1.png"] forState:UIControlStateSelected];
}
The actions should then look like these:
- (IBAction)gd:(UIButton *)sender {
[sender setSelected:!sender.isSelected];
[bdBtn setSelected:NO];
}
- (IBAction)bd:(UIButton *)sender {
[sender setSelected:!sender.isSelected];
[gdBtn setSelected:NO];
}
Here is your solution
Add this Function in the starting , to deselect 2 buttons whenever you tap on button:-
-(void)deselectButtons
{
for(UIView *vw in [self.view subviews])
{
if([vw isKindOfClass:([UIButton class])])
{
UIButton *btn=(UIButton *)vw;
btn.selected=FALSE;
}
}
}
for Good Button:-
- (IBAction)bd:(id)sender {
[self deselectButtons];//add this line of code
UIButton *btn1 = (UIButton *)sender;
if ([sender isSelected]) {
[btn1 setBackgroundImage:[UIImage imageNamed:#"rd.png"] forState:UIControlStateNormal];
[sender setSelected:NO];
} else {
[sender setBackgroundImage:[UIImage imageNamed:#"rd1.png"] forState:UIControlStateNormal];
[sender setSelected:YES];
}
}
for BAD Button:-
- (IBAction)bd:(id)sender {
[self deselectButtons];//add this line of code
UIButton *btn1 = (UIButton *)sender;
if ([sender isSelected]) {
[btn1 setBackgroundImage:[UIImage imageNamed:#"rd.png"] forState:UIControlStateNormal];
[sender setSelected:NO];
} else {
[sender setBackgroundImage:[UIImage imageNamed:#"rd1.png"] forState:UIControlStateNormal];
[sender setSelected:YES];
}
}

iOS UIButton disappears after setting background image to nil

I have a UIButton that has no title or initial background image. When pressed, the button background image changes and when pressed again, it is set to nil. Now with iOS 6.x, the button completely disappears. Here is my code:
- (IBAction)resetAll: (id) sender {
[self reset];
for (UIView *view in self.view.subviews) {
if ([[[view class] description] isEqualToString:#"UIRoundedRectButton"]) {
UIButton *theButton = (UIButton *)view;
int nTag = theButton.tag;
switch (nTag) {
case 11: {
theButton.tag = 10;
[theButton setBackgroundImage:nil forState:UIControlStateNormal];
break;
}
case 21: {
theButton.tag = 20;
[theButton setBackgroundImage:nil forState:UIControlStateNormal];
[theButton setEnabled:YES];
break;
}
case 31: {
theButton.tag = 30;
[theButton setBackgroundImage:nil forState:UIControlStateNormal];
[theButton setEnabled:YES];
break;
}
case 41: {
theButton.tag = 40;
[theButton setBackgroundImage:nil forState:UIControlStateNormal];
[theButton setEnabled:YES];
break;
}
case 51: {
theButton.tag = 50;
[theButton setBackgroundImage:nil forState:UIControlStateNormal];
[theButton setEnabled:YES];
break;
}
}
}
}
return;
This code works fine:
- (IBAction)ButtonClicked: (id) sender {
UIButton *btn = (UIButton *)sender;
// Get the current tag value
int currentTag = [sender tag];
// Toggle the check buttons
if (currentTag == 10 || currentTag == 20 || currentTag == 30 || currentTag == 40 || currentTag == 50) {
[btn setBackgroundImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
btn.tag = ++currentTag;
}
else
if (currentTag == 11 || currentTag == 21 || currentTag == 31 || currentTag == 41 || currentTag == 51) {
[btn setBackgroundImage:nil forState:UIControlStateNormal];
btn.tag = --currentTag;
}
[self calculate];
Any suggestions or help would be appreciated!
Instead of changing the background image of the button in the UIControlStateNormal, why not instead just change states of the button?
If you created the button programmatically, you just need to add the line
[btn setBackgroundImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateSelected];
Then, when pressed and you want it to be the arrow image:
[btn setSelected:YES];
and to set it back to the default appearance:
[btn setSelected:NO];
If you made the button in a XIB, you can set the state images by changing the state config to Selected and set the image there.
Here is the final code implementing DOC's answer. I set the default and selected state in interface builder:
- (IBAction)ButtonClicked: (id) sender {
UIButton *btn = (UIButton *)sender;
if ([btn isSelected ]) {
[btn setSelected:NO];
} else {
[btn setSelected:YES];
}
[self calculate];
}
- (IBAction)resetAll: (id) sender {
[self reset];
for (UIView *view in self.view.subviews) {
if ([[[view class] description] isEqualToString:#"UIRoundedRectButton"]) {
UIButton *theButton = (UIButton *)view;
[theButton setSelected:NO];
}
}
Just an additional answer in case (like me) there is already a good amount of logic around the selected state of the button (parent class gives state to the view based on this). If you need the button to start in an un-selected state with an image and change state to selected with the no image, then you can add a generated blank image to the selected state like so.
//Make a stupid blank image because setting to nil on a state doesn't work.
UIGraphicsBeginImageContextWithOptions(CGSizeMake(23, 23), NO, 0.0);
UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *buttonNonSelectedImage = [UIImage imageNamed:#"video-slomo"];
[self.myButton setBackgroundImage:buttonNonSelectedImage forState:UIControlStateNormal];
[self.mybutton setBackgroundImage:blank forState:UIControlStateSelected];
[self.myButton addTarget:self
action:#selector(onMyButtonPress)
forControlEvents:UIControlEventTouchUpInside];
self.myButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
[self.playRateButton setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[self.view addSubview:self.myButton];
Then, in your button action you can just change the state (and in my case add text).
- (void)onMyButtonPress
{
if (self.myButton.isSelected) {
[self.myButton setSelected:NO];
}
else {
[self.myButton setTitle:#"Selected"]
forState:UIControlStateSelected];
[self.myButton setSelected:YES];
}
}
The accepted answer works in most cases, I just needed the selected state for other tracking info. Happy programming.

Resources