I'm trying to make an app where the user has 4 buttons let's say labeled 1 through 4. If the user taps button-1 then something happens ( I know how to do this part). But let's say I want something new to happen if the user taps button 1 and then button 2. Is there a way to combine taps if so I would greatly appreciate the help.
For this you can use [btn1 isSelected] method ie. you can check if btn1 is selected and then btn 2 is pressed, then perform your desired action.
What you have to do is just select and deselect your buttons when they are tapped and check for their state on other button's action.
- (IBAction)btn1Action:(id)sender {
UIButton *btn1 = (UIButton *)sender;
if ([btn1 isSelected]) {
[btn1 setSelected:NO];
}
else{
[btn1 setSelected:NO];
}
}
- (IBAction)btn2Action:(id)sender {
// Button 1 outlet is myBtn1 (Suppose)
UIButton *btn1 = (UIButton *)sender;
if ([myBtn1 isSelected]) {
// Pressed after button 1
}
else{
// Pressed after button 2
}
}
The code Snippet shared below, gives you an understanding as to how to trigger events for multiple button click combination.
In this case, i have used only a button combination of 2.And I'm disabling the selected buttons once the event is over.
-(IBAction)clickButton:(UIButton *)sender
{
switch (sender.tag) {
case 0:
{
if(_button2.isSelected)
{
//do task for combination of 2,1
_button2.selected=NO;
_button1.selected=NO;
}
if (_button3.isSelected)
{
//do task for combination of 3,1
_button3.selected=NO;
_button1.selected=NO;
}
if(_button4.isSelected)
{
//do task for combination of 4,1
_button4.selected=NO;
_button1.selected=NO;
}
else
{
//do task for button1 alone
_button1.selected=NO;
}
}
break;
case 1:
{
if(_button1.isSelected)
{
//do task for combination of 1,2
_button1.selected=NO;
_button2.selected=NO;
}
if (_button3.isSelected)
{
//do task for combination of 3,2
_button3.selected=NO;
_button2.selected=NO;
}
if (_button4.isSelected)
{
//do task for combination of 4,2
_button4.selected=NO;
_button2.selected=NO;
}
else
{
//do task for button2 alone
_button2.selected=NO;
}
}
case 2:
{
if(_button1.isSelected)
{
//do task for combination of 1,3
_button1.selected=NO;
_button3.selected=NO;
}
if (_button2.isSelected)
{
//do task for combination of 2,3
_button2.selected=NO;
_button3.selected=NO;
}
if (_button4.isSelected)
{
//do task for combination of 4,3
_button4.selected=NO;
_button3.selected=NO;
}
else
{
//do task for button3 alone
_button3.selected=NO;
}
}
case 3:
{
if(_button1.isSelected)
{
//do task for combination of 1,4
_button1.selected=NO;
_button4.selected=NO;
}
if (_button2.isSelected)
{
//do task for combination of 2,4
_button2.selected=NO;
_button4.selected=NO;
}
if (_button3.isSelected)
{
//do task for combination of 3,4
_button3.selected=NO;
_button4.selected=NO;
}
else
{
//do task for button4 alone
_button4.selected=NO;
}
}
case 4:
{
_button1.selected=NO;
_button2.selected=NO;
_button3.selected=NO;
_button4.selected=NO;
}
default:
break;
}
}
Hope it Helps !!!
Related
I'm making a matching game in iOS using objective-C
there's a 12 set of cards (3 columns and 4 rows) which is an array of UIButton connected to IBOutletCollection,the problem is when you tap the first card, you can also tap the other cards simultaneously, but the allowable card to tap must be only 2 cards. How can I prevent tapping of cards, if the tapped cards are greater than 1 and less than 2.
//One action for all buttons
-(void)buttonAction:(UIButton*)button
{
//if user select three button at a time, dont do further operations
if (previousButton && currentButton) {
return;
}
//previous button is the first button
if(previousButton==nil)
{
previousButton=button;
}
//current button is the second button
else if(currentButton==nil)
{
currentButton=button;
}
//if button is selected, set button as not selected and vice versa
if([button isSelected]==NO)
{
[button setSelected:YES];
}
else
{
[button setSelected:NO];
}
//if user press the same button again and again
if (currentButton==previousButton)
{
currentButton=nil;
if([previousButton isSelected]==NO)
{
previousButton=nil;
}
return;
}
else if((currentButton!=previousButton)&&(currentButton!=nil))
{
//both button tags are same, that means both selected state images are same
if(previousButton.tag==currentButton.tag)
{
[self performSelector:#selector(delay) withObject:nil afterDelay:0.5];
}
else
{
[self performSelector:#selector(delayTwo) withObject:nil afterDelay:0.5];
}
}
}
-(void)delay
{
//[currentButton setHidden:YES];
//[previousButton setHidden:YES];
currentButton=nil;
previousButton=nil;
score++;
NSLog(#"Score %d",score);
//the final stage, that means left only two buttons
if(score==6)
{
//[self endGame];
}
}
-(void)delayTwo
{
[currentButton setSelected:NO];
[previousButton setSelected:NO];
currentButton=nil;
previousButton=nil;
}
In viewDidLoad, assign all button selected & normal state images or title as you required
I'm not 100% sure what you are getting at here, but you could try having multiple UITapGestureRecognizer instances. You could have one for 1 tap, one for 2, and one for 3+. That way, you can select the cards for 1 or 2 touches, but ignore it if there are 3 or more.
If my button is in the "selected" state, I want an activity indicator to appear to let the user know that something is happening and that my app is searching for data. I've tried to accomplish this FIRST by using NSLog to see if I can get this method working FIRST. So I did this:
- (void)viewDidLoad
{
[super viewDidLoad];
searchedItem.delegate = self;
if(searchButton.selected == YES)
{
NSLog(#"The button was selected");
}
}
For some reason, it won't work.
Put this checkmark in your button click event. It perfect work when click on button as first time then got to Not Selected and after click on second time go to Selected.
-(IBAction)ClickBtn:(UIButton *)sender
{
sender.selected = ! sender.selected;
if (sender.selected)
{
NSLog(#" Not Selected");
}
else
{
NSLog(#" Selected");
}
}
try this
- (void)viewDidLoad
{
[super viewDidLoad];
searchedItem.delegate = self;
[searchButton setSelected:YES];
if(searchButton.selected == YES)
{
NSLog(#"The button was selected");
}
}
I have strange problem with radio button. I used UIButton for radio button and used two image btnCheck.png and btnUnCheck.png in normal case its working properly there is no problem. this is my code on button click
-(IBAction)btnNextClick:(id)sender {
UIImage* selectedImg=[UIImage imageNamed:#"btnCheck.png"];
if ((btnILink.imageView.image == selectedImg || btnTapeIn.imageView.image == selectedImg || btnKeraLink.imageView.image == selectedImg))
{
if (btnTapeIn.imageView.image == selectedImg) {
UIImage* selectedImg1=[UIImage imageNamed:#"btnCheck.png"];
if (!(btn18.imageView.image == selectedImg1 || btn22.imageView.image == selectedImg1)){
[FunctionManager showMessage:#"" withMessage:#"Please Select Length" withDelegage:nil];
return;
}
}
else {
UIImage* selectedImg1=[UIImage imageNamed:#"btnCheck.png"];
if (!(btn16.imageView.image == selectedImg1 || btn18.imageView.image == selectedImg1 || btn22.imageView.image == selectedImg1)){
[FunctionManager showMessage:#"" withMessage:#"Please Select Length" withDelegage:nil];
return;
}
}
}
else {
[FunctionManager showMessage:#"" withMessage:#"Please Select Method" withDelegage:nil];
return;
}
}
its working properly when I click on btnNext, if no any one item is selected then it display message. but problem is When I select the both item and go in background then I comeback in the app and click on next then it display the message, but Check box already selected. why the condition is not true in that case...
Yes It will do so, because you compared UIImage object Like:
UIImage* selectedImg=[UIImage imageNamed:#"btnCheck.png"];
if ((btnILink.imageView.image == selectedImg || btnTapeIn.imageView.image == selectedImg || btnKeraLink.imageView.image == selectedImg))
Every time when its came from background it sets Create new UIImage object So it can not be the same object.
So instead of comparing object(btnILink.imageView.image == selectedImg) take a bool Value it will work fine.
Use Buttons selected property instead of image when click on that button for checking
like
if(btnTapeIn.selected)
{
[btnTapeIn setImage:[UIImage imageNamed:#"btnUnCheck.png"] forState:UIControlStateNormal];
btnTapIn.selected = NO;
}
else
{
[btnTapeIn setImage:[UIImage imageNamed:#"btnCheck.png"]forState:UIControlStateNormal];
btnTapIn.selected = YES;
}
https://github.com/Brayden/UICheckbox
You can implement this and decrease the comparison logic.
You should not compare by the button's set image. Use the button's built in selected property for example.
btnTapeIn.selected = YES;
...
if(btnTapeIn.isSelected)
...
- (IBAction)btn_GenderCheck:(id)sender {
switch ([sender tag])
{
case 1: //-------for Male
[btn_malecheck setImage:[UIImage imageNamed:#"radio_select.png"] forState:UIControlStateNormal];
[btn_femalecheck setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateNormal];
isMaletag=1;
break;
case 2: //----------for Female
[btn_malecheck setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateNormal];
[btn_femalecheck setImage:[UIImage imageNamed:#"radio_select.png"] forState:UIControlStateNormal];
isMaletag=2;
break;
default:
break;
}
}
// then you can check tag and accordingly alert your message
You can set images in for normal state and selected in XIB and change the state in IBAction
In my xib I have taken 4 UIbuttons named button 1, 2, 3 and 4. These four buttons are connected two four different IBAction methods which perform different functions.
Now I have one more button called "Save" This has also a different IBAction method.
- (IBAction)Save:(id)sender
{
}
Now here I want to check which of the above 4 UIButtons have been clicked.
For this I tried checking this way
- (IBAction)Save:(id)sender
{
if(sender == button1)
{
//Do this
}
else if (sender == button2)
{
//Do this
}
}
But this is not working. I am doing something wrong.Please help me out
Regards
Ranjit.
You can set the tag values for each button in the interface builder and set actions of all buttons to this method
//set global variable flag.
int flag;
- (IBAction)buttonClicked:(id)sender
{
switch ([sender tag])
{
case 0:
{
flag =0;
// implement action for first button
}
break;
case 1:
{
flag =1;
// implement action for second button
}
break;
case 2:
{
flag =2;
// implement action for third button
}
break;
//so on
default:
break;
}
}
for save button
- (IBAction)save:(id)sender
{
switch (flag)
{
case 0:
{
// first button clicked
}
break;
case 1:
{
// second button clicked
}
break;
case 2:
{
// third button clicked
}
break;
//so on
default:
break;
}
}
Define a class level ivar as
UIButton *selectedBtn;
Then in you IBActions
- (IBAction)button1:(id)sender {
selectedBtn = sender // or button1
}
- (IBAction)button2:(id)sender {
selectedBtn = sender // or button2
}
- (IBAction)button3:(id)sender {
selectedBtn = sender // or button3
}
- (IBAction)button4:(id)sender {
selectedBtn = sender // or button4
}
- (IBAction)Save:(id)sender
{
//Check output of below statement to ensure you're getting a sender
NSLog(#"Sender: %#", sender);
if(selectedBtn == button1)
{
NSLog(#"Button 1 pressed");
//Do this
}
else if (selectedBtn == button2)
{
NSLog(#"Button 2 pressed");
//Do this
}
else if (selectedBtn == button3)
{
NSLog(#"Button 3 pressed");
//Do this
}
else if (selectedBtn == button4)
{
NSLog(#"Button 4 pressed");
//Do this
}
}
Can you try this:
- (IBAction)Save:(id)sender
{
UIButton *pressedButton = (UIButton*)sender;
//Check output of below statement to ensure you're getting a sender
NSLog(#"Sender: %#", sender);
if([pressedButton isEqual:button1])
{
NSLog(#"Button 1 pressed");
//Do this
}
else if ([pressedButton isEqual:button2])
{
NSLog(#"Button 2 pressed");
//Do this
}
}
In your save method, check the Selected property of the other 4 buttons. If you do not want to keep the buttons in a selected state, but just want to see if they were clicked at some point, then define a property (e.g. an array) to track which buttons were clicked during the session, and check this property in your save method.
I have an UIButton array like this:
#property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *btn_Impact_Collection;
and I have this function:
- (IBAction)impactAction:(id)sender;
In the XIB file I have nine button, each button is connected to btn_Impact_Collection Array with the Referencing Outlet Collection. Moreover the Touch_inside property of each button is connected to the function ImpactAction.
Now, when a button is clicked the ImpactAction function is called, but inside this function, how can i know which button is pressed?
Thanks in advance for the answer!
Cast sender to UIButton class, and that will give you the instance of the clicked button. I don't have Xcode with me but something like:
if ([sender isMemberOfClass:[UIButton class]])
{
UIButton *btn = (UIButton *)sender;
// Then you can reference the title or a tag of the clicked button to do some further conditional logic if you want.
if([btn.currentTitle isEqualToString:#"title of button"])
{
// do something.
}
else if(etc...)
}
Set tags for each button in interface builder (1-9), then say
if ([sender tag] == 1) {
//First button was pressed, react.
}
else if ([sender tag] == 2) {
//Second button was pressed, react.
}
// Etc...
else {
//Last button was pressed, react.
}
And the same for all the others, or you could put it in a switch.
Rather than do a string check on the title (which is slow and can be tedious) you can:
- (void)buttonPressed:(id)sender
{
for( UIButton *button in self.buttonCollection )
{
if( sender == button )
{
// sender is your button (eg. you can access its tag)
}
}
}
Another option.. Cast sender to check if it's a UIButton, then switch sender.tag:
if ([sender isMemberOfClass:[UIButton class]]) {
switch ([sender tag]) {
case 0:
//do stuff for button with tag 0
break;
case 1:
//do stuff for button with tag 1
break;
case 2:
....
break;
default:
break;
}
}