Trouble using UiButton as toggle switch - ios

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.

Related

Perform three different action for a single button

I want to perform three different actions for a single button. I surfed in google also it shows some different options but those are not helpful.
I have declared NSInteger inside CustomUIButton i.e. click and initialize inside IBAction to 0.
Here is the code.
-(void)changeStudentAction:(id)sender
{
CustomUIButton *button=sender;
NSInteger flag = 0;
button.click=0;
if(button.click==0)
{
button.click=1;
[button setSelected:NO];
[button setBackgroundImage:[UIImage imageNamed:#"Absent_on_coloured.png"] forState:UIControlStateNormal];
flag=0;
}
else if (button.click==1)
{
button.click=2;
[button setSelected:YES];
[button setBackgroundImage:[UIImage imageNamed:#"Present_on_coloured.png"] forState:UIControlStateNormal];
flag=1;
}
else if (button.click==3)
{
button.click=0;
[button setBackgroundImage:[UIImage imageNamed:#"Late_on_coloured.png"] forState:UIControlStateNormal];
[button setSelected:YES];
flag=3;
}
}
But it is not working. Can someone tell me where I am doing wrong.
Define button.click=0; globally so initially its value will be zero and after that it will increase.
#interface yourclass : superclass
{
int click;
}
- (void)viewDidLoad{
click=0;
}
-(void)changeStudentAction:(id)sender
{
CustomUIButton *button=sender;
NSInteger flag = 0;
if(click==0)
{
click=1;
[button setSelected:NO];
[button setBackgroundImage:[UIImage imageNamed:#"Absent_on_coloured.png"] forState:UIControlStateNormal];
flag=0;
}
else if (button.click==1)
{
click=2;
[button setSelected:YES];
[button setBackgroundImage:[UIImage imageNamed:#"Present_on_coloured.png"] forState:UIControlStateNormal];
flag=1;
}
else if (button.click==3)
{
click=0;
[button setBackgroundImage:[UIImage imageNamed:#"Late_on_coloured.png"] forState:UIControlStateNormal];
[button setSelected:YES];
flag=3;
}
}
You are setting the button.click = 0 for every action.
So every time you click it is being set to zero.
You can instead keep a separate variable to count in your view controller than having a click property on button. Hope this helps :-)
According to your code,
it was always goes on
if(button.click==0)
{
button.click=1;
[button setSelected:NO];
[button setBackgroundImage:[UIImage imageNamed:#"Absent_on_coloured.png"] forState:UIControlStateNormal];
flag=0;
}
I will give you better suggestion instead of "click" you can use "tag" option which was the one property of uibutton.
First you have to define a custom button on .h file and then set the tag = 0 in - (void)viewDidLoad
method.
CustomUIButton *button;
NSInteger flag = 0;
button.click=0;
use it this way or as simple from all such problems use some other variable as
because every time this function is call its zero every time so make it outside this function and use it
NSInteger flag = 0;
int counter = 0;
-(void)changeStudentAction:(id)sender
{
if(counter ==0)
{
counter =1;
[button setSelected:NO];
[button setBackgroundImage:[UIImage imageNamed:#"Absent_on_coloured.png"] forState:UIControlStateNormal];
flag=0;
}
else if (counter ==1)
{
counter =2;
[button setSelected:YES];
[button setBackgroundImage:[UIImage imageNamed:#"Present_on_coloured.png"] forState:UIControlStateNormal];
flag=1;
}
else if (counter ==3)
{
counter =0;
[button setBackgroundImage:[UIImage imageNamed:#"Late_on_coloured.png"] forState:UIControlStateNormal];
[button setSelected:YES];
flag=3;
}
}
in start button tag to zero then change as following
-(void)changeStudentAction:(id)sender{
CustomUIButton *button=sender;
NSInteger flag = 0;
if(button.tag==0)
{
button.tag=1;
}
else if (button.tag==1)
{
button.tag=2;
}
else if (button.click==3)
{
button.tag=0;
}
}
Please try following code may be solve your problem.
-(void)changeStudentAction:(id)sender
{
CustomUIButton *button=sender;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
[button setBackgroundImage:[UIImage imageNamed:#"Absent_on_coloured.png"] forState:UIControlStateNormal];
[UIView setAnimationDuration:0.4];
[button setBackgroundImage:[UIImage imageNamed:#"Present_on_coloured.png"] forState:UIControlStateNormal];
[UIView setAnimationDuration:0.6];
[button setBackgroundImage:[UIImage imageNamed:#"Late_on_coloured.png"] forState:UIControlStateNormal];
[UIView commitAnimations];
}

UIButton causing a crash

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

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

how to select all inside IBOutletCollection

I created a IBOutletCollection property and action for button1 to button9. Each and every button is pressed color will change,
-(IBAction)btnCollectionAction:(id)sender {
counter = 0;
btnSelecter = sender;
if (counter == 0) {
[btnSelecter setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
counter = 1;
}
else {
[btnSelecter setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
counter = 0;
}
}
IBOutlet for selectall button,
- (IBAction)selectButtonFunction1:(id)sender {
if (counter == 0) {
[selBtn1 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
counter = 1;
}
else {
[selBtn1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
counter = 0;
}
}
the above both script works well.
My question is - if i pressed the select all button (change to whiteColor), the above all nine button must change to whiteColor else blackColor.
I tried like this:
if(selBtn1.touchInside) {
[btnSelecter setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
else {
[btnSelecter setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
}
it will change only one button instead of all.
Last part of your question is vague, I didn't understand the last portion. From your title I understand that you need to get all the UIButton from IBOutletCollection. I'm answering for that question.
You can toggle the color like:
- (IBAction)selectAll:(id)sender
{
for (UIButton *button in buttonCollection)
{
if([button titleColorForState:UIControlStateNormal] isEqual:[UIColor blackColor]])
{
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
else
{
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
}
}
}
Try this approach:
1. Create IBOutletCollection with all your buttons (You Allready done this)
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *myButtons;
2. Iterate throughout collection to configure target and appearence for each button:
for (UIButton *button in self.myButtons)
{
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
// Do any additional configuration here
}
3. Add target to selectAll button and assign Tag property for selectAll button
[selecAllButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
selectAllButton.tag = 10000; // you can other tag number
4. Create buttonPressed: Handler
-(void) buttonPressed:(UIButton *)sender
{
if(sender.tag = 10000)
{
for (UIButton *button in self.menuButtons) {
if([button isKindOfClass:[UIButton class]]){
button.selected = YES;
}
}
} else
{
// handle other button actions
}
}

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