I have 2 buttons, each one with tag. how can I compare between them, each with his own tag and image. for example:
// sender is (UIButton *)sender.
if ((sender.tag == 1)theImageOnTheButton == (sender.tag == 2)theImageOnTheButton
{
// egual
}
else
// not egual
so, if the sender than tagged as 1, his image is equal to the sender with tag 2, his image are equal, say equal, else, say that they are not egual. how can I do that?
the original code is:
-(void)flipView:(UIButton*)sender
{
x = x + 1;
if (x == 1)
{
// When flipping the first card
NSLog(#"X == 1");
[sender setTag:1];
}
else if (x == 2)
{
// When flipping the second card
NSLog(#"X == 2");
x = 0;
[sender setTag:2];
if ((sender.tag == 2) == (sender.tag == 1))
{
NSLog(#"IGUAL");
}
else
{
NSLog(#"NOT EGUAL");
}
}
}
Thanks allot.
[sender setTag:2];
and then -
if ((sender.tag == 2) == (sender.tag == 1))
when already tag is set to 2, then how can it be equal to 1? Wrong logic.
If I have more than two buttons then how can i compare the images?
suppose you have two buttons with tags
IBOutlet UIButton *btn1, *btn2;
btn1.tag = 1;
btn2.tag = 2;
connect these two IBOutlet buttons to your buttons in your xid file and for both add a common IBAction.
-(IBAction)checkingBtns:(id)sender
{
if([sender tag] == 1){
//Do what ever with your btn1 change color, change text, change image
}
if([sender tag] == 2){
//Do what ever with your btn2 change color, change text, change image
}
}
hope this will help you !! properly connect the oulets and actions for proper function
Related
I have a view controller and it contains n number of UITextFields and UItextViews and UILabels, is there anyhow I can get notified if any of them changes..?
I can do it by manually looking at each of them in their respective TextDidChangeNotification and similar but I am looking for a more optimized way of doing this, where I don't have to worry about each of them .
// Assumes you don't use tag values now - if you do small change to create
// and index set, add the ones you use, so all new ones assigned are unique.
// assumes ARC
1) New ivar:
{
NSMutableDictionary *savedValues;
}
1) When you want to baseline the values:
savedValues = [self snapshot];
2) call this to baseline current values initially then at any later point:
- (NSMutableDictionary *)snapshot
{
NSInteger tag = 1;
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:[self.view.subviews count]];
for(UIView *v in self.view.subviews) {
if([v isKindOfClass:[UILabel class]] || [v isKindOfClass:[UITextField class]] || [v isKindOfClass:[UITextView class]]) {
if(v.tag == 0) v.tag = tag++; // will happen once
// EDIT below
[dict setObject:[NSString stringWithString:[(id)v text]] forKey:[NSNumber numberWithInteger:tag]];
}
}
return dict;
}
4) When you want to see if anything changed:
- (BOOL)anyChanges
{
NSDictionary *currentDict = [self snapshot];
return [currentDict isEqualToDictionary:savedValues];
}
You should use one method for all textFields, textView and Labels. and give a unique tag to textFields and textViews and labels. which help you for define it's textField ,textView or Label.
if(sender.tag == 1000)//UILabel
{
UILabel *label=(UILabel *)sender
//write own code for label what do you want.
}
else if(sender.tag == 2000)//UITextField
{
UITextField *textField=(UITextField *)sender
//write own code for textField what do you want.
}
else if(sender.tag == 3000)// UITextView
{
UITextView *textView=(UITextView *)sender
//write own code for textView what do you want.
}
Make your class to handle UIControlEventValueChanged event in your textfield, textview or label's value is changed. Add this line ViewDidLoad method:
[youLabel addTarget:self action:#selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
// add for textfield, textview also if needed
[youTextField addTarget:self action:#selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
[youTextView addTarget:self action:#selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
Now selector would be called when ever value is changed
- (void) valueChanged:(id)sender{
if(sender isKindofClass[UILabel class])
{
//label value changed here to differntiate used tag
if([sender tag] == 0)
....
....
}
else if(sender isKindofClass[UITextField class])
{
// textField value changed to differntiate used tag
if([sender tag] == 0)
....
....
}
else if(sender isKindofClass[UITextView class])
{
// textview value changed to differntiate used tag
if([sender tag] == 0)
....
....
}
}
As My Screen shot show that i am working on word matching game.In this game i assign my words to different UIButtons in Specific sequence on different loctions(my red arrow shows this sequence)and of rest UIButtons i assign a one of random character(A-Z).when i Click on any UIButtons its title will be assign to UILabel which is in Fornt of Current Section:i campare this UILabel text to below UILabels text which is in fornt of timer.when it match to any of my UILabels its will be deleted.i implement all this process already.
But my problem is that which is show by black lines.if the player find the first word which is "DOG". he click the Two UIButtons in Sequence,but not press the Third one in Sequence.(as show by black line).so here i want that when player press the any UIButtons which is not in Sequence then remove the previous text(which is "DO") of UILabel and now the Text of UILabel is only "G" .
Here is my code to get the UIButtons titles and assign it UILabel.
- (void)aMethod:(id)sender
{
UIButton *button = (UIButton *)sender;
NSString *get = (NSString *)[[button titleLabel] text];
NSString *origText = mainlabel.text;
mainlabel.text = [origText stringByAppendingString:get];
if ([mainlabel.text length ]== 3)
{
if([mainlabel.text isEqualToString: a]){
lbl.text=#"Right";
[btn1 removeFromSuperview];
score=score+10;
lblscore.text=[NSString stringWithFormat:#"%d",score];
words=words-1;
lblwords.text=[NSString stringWithFormat:#"%d",words];
mainlabel.text=#"";
a=#"tbbb";
}
else if([mainlabel.text isEqualToString: c]){
lbl.text=#"Right";
[btn2 removeFromSuperview];
score=score+10;
lblscore.text=[NSString stringWithFormat:#"%d",score];
words=words-1;
lblwords.text=[NSString stringWithFormat:#"%d",words];
mainlabel.text=#"";
c=#"yyyy";
}
else
if([mainlabel.text isEqualToString: d]){
lbl.text=#"Right";
[btn3 removeFromSuperview];
score=score+10;
lblscore.text=[NSString stringWithFormat:#"%d",score];
words=words-1;
lblwords.text=[NSString stringWithFormat:#"%d",words];
mainlabel.text=#"";
d=#"yyyy";
}
else {
lbl.text=#"Wrong";
mainlabel.text=#"";
}
}}
Thanx in advance
Assign tag to each button from left to right.
So you will have,
GButton.tag = 0;
TButton.tag = 1;
DButton.tag = 2;
.
.
.
VButton.tag = 9;
.
.
.
EButton.tag = 18;
.
.
.
CButton.tag = 26;
Now keep the track of previous pressed button and current pressed button.
Call below function when your button delegate hits:
Write below code into your .h file
#define SEQ_TYPE_ANY 0
#define SEQ_TYPE_RIGHT 1
#define SEQ_TYPE_LEFT 2
#define SEQ_TYPE_TOP 3
#define SEQ_TYPE_BOTTOM 4
#define SEQ_TYPE_RIGHT_DIAGONAL_DOWN 5
#define SEQ_TYPE_RIGHT_DIAGONAL_UP 6
#define SEQ_TYPE_LEFT_DIAGONAL_DOWN 7
#define SEQ_TYPE_LEFT_DIAGONAL_UP 8
#define NO_OF_BUTTONS_IN_ROW 9
//Add below variables into your class
int curentSequence;
UILabel *resultLabel;
UIButton *previousButton;
//Declare property for previousButton
#property(nonatomic, retain) UIButton *previousButton;
//Write below code to .m file
#synthesize previousButton;
-(BOOL) isAdjacent:(UIButton *)currentButton
{
if(previousButton == nil)
{
resultLabel.text = currentButton.titleLabel.text;
curentSequence = SEQ_TYPE_ANY;
return TRUE;
}
if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT) &&
(previousButton.tag + 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_ANY;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT) &&
(previousButton.tag - 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_LEFT;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_TOP) &&
(previousButton.tag - NO_OF_BUTTONS_IN_ROW == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_TOP;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_BOTTOM) &&
(previousButton.tag + NO_OF_BUTTONS_IN_ROW == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_BOTTOM;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT_DIAGONAL_DOWN) &&
(previousButton.tag + NO_OF_BUTTONS_IN_ROW + 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_RIGHT_DIAGONAL_DOWN;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_RIGHT_DIAGONAL_UP) &&
(previousButton.tag - NO_OF_BUTTONS_IN_ROW + 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_RIGHT_DIAGONAL_UP;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT_DIAGONAL_UP) &&
(previousButton.tag - NO_OF_BUTTONS_IN_ROW - 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_LEFT_DIAGONAL_UP;
return TRUE;
}
else if((curentSequence == SEQ_TYPE_ANY || curentSequence == SEQ_TYPE_LEFT_DIAGONAL_DOWN) &&
(previousButton.tag + NO_OF_BUTTONS_IN_ROW - 1 == currentButton.tag))
{
resultLabel.text = [resultLabel.text stringByAppendingString:currentButton.titleLabel.text];
curentSequence = SEQ_TYPE_LEFT_DIAGONAL_DOWN;
return TRUE;
}
else
{
resultLabel.text = #"";
curentSequence = SEQ_TYPE_ANY;
return FALSE;
}
}
// Event handler for button event
- (void)aMethod:(id)sender
{
UIButton *currentButton = (UIButton *)sender;
BOOL result = [self isAdjacent:currentButton];
if(result == FALSE)
{
self.previousButton = nil;
resultLabel.text = #"";
curentSequence = SEQ_TYPE_ANY;
}
else
{
self.previousButton = sender;
}
}
Hope it will help.
If I understand correctly, you need to know if the pushed button is adjacent to the previously pushed button? Use this function to test for adjacency in the grid:
bool isAdjacent(UIButton* current, UIButton* previous) {
if( !previous )
return false;
//Create a rectangle around the previous button (assuming all buttons are in a fixed grid)
CGRect previousRect = previous.frame;
CGRect adjacentRect = CGRectMake(previous.frame.origin.x - previous.frame.size.width,
previous.frame.origin.y - previous.frame.size.height,
previous.frame.size.width*3,
previous.frame.size.height*3);
return CGRectIntersectsRect(adjacentRect, previousRect);
}
And only append if they are adjacent, ie:
- (void)aMethod:(id)sender
{
UIButton *button = (UIButton *)sender;
static UIButton* previous = nil;
NSString *get = (NSString *)[[button titleLabel] text];
NSString *origText = mainlabel.text;
if( isAdjacent(button, previous) )
mainlabel.text = [origText stringByAppendingString:get];
previous = button;
//Rest of function
}
Fun question:
In this particular case, I agree with Luke about subclassing the UIButton. This way you could give each button an (X, Y) on your grid, as well as a (Xnext, Ynext) list for all of the possible expected next press locations (if the button itself can be used to make multiple words). Externally you will compare the currently being hit against the expected (Xnext, Ynext). If the two dont match, this is the signal you are looking for.
This is an answer that accounts for all of your situations, forward and backward horizontal (if you choose to implement backware), upward and downward vertical (if you choose to implement upward), and any diagonal, or any other combination you can come up with!
This also accounts for lets say hitting the D, then the O then trying to press the D again versus hitting the G. It also takes care of hitting the incorrect G.
Create a new .m .h pair of files (a new object) and give it your name.
Some example code for implementing a custom UIButton (h file):
#interface myConnectedUIButton : UIButton {
BOOL isAWordBeginCharacter;
unsigned int beginWordKey;
unsigned int myGridX;
unsigned int myGridY;
NSMutableArray * myConnectedSet;
}
-(id)init;
-(void)initWithGridX:(unsigned int)X GridY:(unsigned int)Y BeginChar:(BOOL)yesNo BeginWordKey:(unsigned int)key;
-(void)setGridPosWithX:(unsigned int)X Y:(unsigned int)Y;
-(void)setGridX:(unsigned int)X;
-(void)setGridY:(unsigned int)Y;
-(unsigned int)getGridX;
-(unsigned int)getGridY;
-(void)setIsABeginChar:(BOOL)yesNo;
-(BOOL)getIsABeginChar;
-(void)addPosToConnectedSetGridX:(unsigned int)X GridY:(unsigned int)Y WordKey:(unsigned int)key;
-(NSArray *)getMyConnectedSetArray;
-(void)clearConnectedSet;
#end
In the .m file of your
#implementation myConnectedUIButton
-(id)init{
[super init];
// Lets go ahead and initialize the NSMutableArray here also IFF it hasnt already been allocated
if( nil == myConnectedSet ){
myConnectedSet = [[NSMutableArray alloc] init];
}
// Lets also zero out the x, y position
myGridX = 0;
myGridY = 0;
// Lets also state that this is NOT a begin char for the time being and 0 for the begin char key
isAWordBeginCharacter = NO;
beginWordKey = 0;
return self;
}
-(void)initWithGridX:(unsigned int)X GridY:(unsigned int)Y BeginChar:(BOOL)yesNo BeginWordKey:(unsigned int)key{
// Lets go ahead and initialize the NSMutableArray here also IFF it hasnt already been allocated
if( nil == myConnectedSet ){
myConnectedSet = [[NSMutableArray alloc] init];
}
myGridX = X;
myGridY = Y;
isAWordBeginCharacter = yesNo;
beginWordKey = key;
}
-(void)setGridPosWithX:(unsigned int)X Y:(unsigned int)Y{
myGridX = X;
myGridY = Y;
}
-(void)setGridX:(unsigned int)X{
myGridX = X;
}
-(void)setGridY:(unsigned int)Y{
myGridY = Y;
}
-(unsigned int)getGridX{
return myGridX;
}
-(unsigned int)getGridY{
return myGridY;
}
-(void)setIsABeginChar:(BOOL)yesNo{
isAWordBeginCharacter = yesNo;
}
-(BOOL)getIsABeginChar{
return isAWordBeginCharacter;
}
-(void)addPosToConnectedSetGridX:(unsigned int)X GridY:(unsigned int)Y WordKey:(unsigned int)key{
[myConnectedSet addObject:[GridPointNext GridPointNextWithX:X GridPointY:Y NextWordKey:key]];
}
-(NSArray *)getMyConnectedSetArray{
return myConnectedSet;
}
-(void)clearConnectedSet{
[myConnectedSet removeAllObjects];
}
-(void)dealloc{
[myConnectedSet release];
[super dealloc];
}
#end
You will also now need a "GridPointNext" object.
The Grid Object header should look as follows:
#interface GridPointNext : NSObject {
unsigned int GridPointX;
unsigned int GridPointY;
unsigned int nextWordKey;
}
+(GridPointNext *)GridPointNextWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key;
-(id)initWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key;
-(unsigned int)getGridX;
-(unsigned int)getGridY;
-(unsigned int)getNextWordKey;
#end
The m file for the object should look as follows:
#implementation GridPointNext
+(GridPointNext *)GridPointNextWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key{
GridPointNext * aPoint = [[GridPointNext alloc] initWithX:X GridPointY:Y NextWordKey:key];
[aPoint autorelease];
return aPoint;
}
-(id)initWithX:(unsigned int)X GridPointY:(unsigned int)Y NextWordKey:(unsigned int)key{
GridPointX = X;
GridPointY = Y;
nextWordKey = key;
return self;
}
-(unsigned int)getGridX{
return GridPointX;
}
-(unsigned int)getGridY{
return GridPointY;
}
-(unsigned int)getNextWordKey{
return nextWordKey;
}
#end
You will have to deal with the dealloc portion. This at least give you some tools for creating your custom button and your word list algorithm around it.
If I understand correctly. The user can only have a correct word, if the letters chosen are all sitting next to each other?
Have you tried this:
Keep two references. One UIButton for previousPressedButton and one UIButtonfor lastPressedButton.
First a user presses D. lastPressedButton will refer to the D.
Then a user presses O. previousPressedButton will be D. lastPressedButton will be O.
Now, get the width and height of the UIButtons and compare if the lastPressedButton.frame.origin.x will be less than width or -width away.
Also check if the lastPressedButton.frame.origin.y will be less than height or -height away.
Now you know if it's touching the previous button. Use this to decide if it's a new word or not.
I would put this into a method.
-(BOOL)isAdjacentLetter {
float buttonWidth = lastPressedButton.size.width;
float buttonHeight = lastPressedButton.size.height;
if(lastPressedButton.frame.origin.x>previousPressedButton.frame.origin.x+buttonWidth) return NO;
if(lastPressedButton.frame.origin.y>previousPressedButton.frame.origin.y+buttonHeight) return NO;
if(lastPressedButton.frame.origin.x<previousPressedButton.frame.origin.x-buttonWidth) return NO;
if(lastPressedButton.frame.origin.y<previousPressedButton.frame.origin.y-buttonHeight) return NO;
return YES;
}
Then whenever a button is clicked. you can use
if ([self isAdjacentLetter]) {
//still same word
} else {
//new word. erase
}
Or, if I understand differently. The words can only be made when the letters are in a row.Such as : From left to right. From down to up. From bottom right to top left etc.
In this case, determine all directions.
Such as, top left is 0, top is 1, top right is 2. right is 3. down right is 4. down is 5. down left is 6. left is 7.
When two buttons are clicked, store the directions. For example:
If it's from left to right, direction = 3;
Then when another button is clicked, check the new direction. If it's 3, the word is still in the same direction. if it's something else, then erase and start over.
Hope this helps.
I have implemented several of UISegmentedControl objects before but for one or other reason I am unable to implement it within a tableview cell. I want the user to choose his gender. if the value of the segmentedControl changed a method gets called to save it for further processing.
self.seg = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:#"Man",#"Female", nil]];
[self.seg addTarget:self action:#selector(toggleGender) forControlEvents:UIControlEventValueChanged];
I created the method:
-(void)toggleGender{
NSLog(#"%d",self.seg.selectedSegmentIndex)
if (self.seg.selectedSegmentIndex == 0)
{
NSLog(#"User is a man");
} else if (self.seg.selectedSegmentIndex == 1)
{ NSLog(#"User is a female");
}
}
The first NSLog prints -1 as value if the value has changed.
I declared seg in the header file, and created a property and synthesized it!
I am currently NOT dealllocing this object. (I know this is a memory leak)
Why am I unable to read-out the selected segment, and why does it give back -1 as selected item?
Try this :
self.seg = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:#"Man",#"Female", nil]];
[self.seg addTarget:self action:#selector(toggleGender:) forControlEvents:UIControlEventValueChanged];
(NOTE THE ':' in the #selector..). And change your function by this :
-(void)toggleGender:(id)sender
{
if ([sender isKindOfClass:[UISegmentedControl class]])
{
NSLog(#"%d",[(UISegmentedControl *)sender selectedSegmentIndex]);
if ([(UISegmentedControl *)sender selectedSegmentIndex] == 0)
{
NSLog(#"User is a man");
}
else if ([(UISegmentedControl *)sender selectedSegmentIndex] == 1)
{
NSLog(#"User is a female");
}
}
}
i'm new to iPhone.Is there any way to set 3 images to button, and when I will click the button it will change button image in a circle ? Thanks...
In your IBAction method for the button click, you can keep a count of which image you are on, and also have all 3 UIImages ready to go (so there isn't the load everytime..unless the images are large (which they shouldn't be for a button) and check it and rotate it basically with something simple like (assumes you have 3 instance variables of UIImages ready that are already initialized with the images.:
-(IBAction) myButtonPress:(id)sender {
int imageCounter = 0;
if(imageCounter == 0) {
[myButtonImage setBackgroundImage:image1 forState:UIControlStateNormal];
imageCounter++;
}
else if(imageCounter == 1) {
[myButtonImage setBackgroundImage:image2 forState:UIControlStateNormal];
imageCounter++;
}
else if(imageCounter == 2) {
[myButtonImage setBackgroundImage:image3 forState:UIControlStateNormal];
imageCounter = 0;
}
//Do other button press stuff
}
First off I am a rookie so any help is appreciated. I have written the following code to change the title of the button every time it is initiated. When I test the code, I can see the new button label for a fraction of a second and then the button is blank again (as it had started off). I only see the first three touches, so I am thinking that there is also something wrong with my counting method. The code is as follows:
-(IBAction)pressButton:(id)sender {
static int counter = 0;
if (counter == 0) {
[[sender titleLabel] setText:#"not answered"];
}else if (counter == 1) {
[[sender titleLabel] setText:#"Pressed Once"];
}else if (counter == 2) {
[[sender titleLabel] setText:#"Pressed Twice"];
}
counter += 1;
if (counter >2) {
counter = 0;
}
}
Thank you in advance for your help!
You want to use:
[(UIButton *)sender setTitle:#"XXX" forState:UIControlStateNormal];
Setting the label directly isn't going to work because it's manipulated internally by the button logic.