How to distinguish dynamically generated button on selection using iPhone SDK? - iphone

In my iPhone app, I have array of buttons that are dynamically generated based on user selection.
How do I distinguish selected button from others?
I want that when user select the other button the previously selected button should go back to its normal state in terms of its looks. I am unable to revert the previously selected buttons to its normal state.

Use tag to identify the button.
At the time of creating buttons you can assign tag as number to the button and use the same to identify.
yourButton.tag = intNumber;

You have an array of the buttons. You can loop through your array and check if it is the one that was clicked.
- (IBAction) buttonClicked:(id)sender {
for(int i; i < [array count]; i++){
if((UIButton *)sender == (UIButton *)[array objectAtIndex:i])
//do something
else
//do something else
}
Something like that.

Try setting tag for each button,using
yourButton.tag=intValue; //intValue>0
Your buttonAction should be as follows,
-(IBAction)buttonAction:(id)sender
Save the previously selected tag, and change the value accordingly.

you can loop through your subviews and set for all the old style:
- (void)highlightImgWithID:(int)packID {
[self.view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UIImageView class]]) {
[(UIImageView*)obj setHighlighted:([obj tag] == IDtoSelectNext)];
}
}];
}
The sample is how I currently implement it in my App with UIImageView's you can change it to work with buttons.

Related

UIKeyboard delegate on ".?123" key

Does anyone have an idea if we get a delegate call back from the keyboard when ".?123" button is tapped on it? We have put a customized number pad on the text keypad and want to remove it once user taps on ".?123" button to avoid duplicate keys.
Any suggestions.
There isn't any notification that will give you what you want. In fact, there isn't any public API that gives you access to the keyboard at that level. The only way I can think of to do this, is to put a transparent button over top the .?123 key, and detect that, and then pass on the touch to the underlying button. The button views are buried very deeply in the view hierarchy. I used this code to first, find the keyboard, and then log the views (UIKBKeyViews) that include that button. The five views in the log below appear to be the uppercase,backspace,.?123,spacebar, and return views.
-(void) keyboardUp: (NSNotification*) notification { // called from UIKeyboardDidShowNotification
UIWindow *tempWindow = [[[UIApplication sharedApplication] windows]objectAtIndex:1];
UIView *keyboard;
for(int i = 0; i < [tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
// NSLog(#"Keyboard subviews are: %#",keyboard.subviews);
NSLog(#"%#",[[[[[[[[[[[[[UIApplication sharedApplication] windows]objectAtIndex:1] contentView]subviews]lastObject]subviews]lastObject]subviews]lastObject]subviews]lastObject]subviews]);
}
}
}

How to determine if a cell contains a button

I've created a cell named CELL .
My first task is add a button on the cell, which I have successfully added.
However, while retrieving the CELL I need to know if the cell is the reusable cell or not. If not, then create the cell and add the button, but if the cell exists and button does not, I need to add the button.
In my XIB I added the button in the cell. In some cells I need to show the button and in some I don't.
How can I determine if the cell contains a button? And if it does contain a button can I tag it?
Use -
for( int i =0 ; i < [cell.subviews count]; i++) {
if ([[cell.subviews objectAtIndex:i] isKindOfClass:[UIButton Class]] ) {
//Button is found, do whatever you want
UIButton *button = [cell.subviews objectAtIndex:i];
int tag = button.tag;
}
}
One approach is to iterate though subview which I personally think is bad idea.
The other approach is to set the tag of the cell say 100 for containing button.
Then you can check
if (cell.tag == 100) {
// Cell with button
} else {
// Cell without button
}

Linking multiple buttons to one method with different jobs

I have a huge crazy scene in my story board that has 36 different buttons, and each one means something different when clicked on. I really don't want to go about creating 36 different methods, so how could I reference a button title or button name in a method that is called when one of the 36 buttons is pushed.
This is probably a simple question, but I'm new to iOS and Objective C...
Thanks!
You can create a single method, like so:
- (IBAction)buttonTapped:(id)sender{
// The button that was tapped is called "sender"
// This will log out the title of the button
//NSLog(#"Button: %#", sender.titleLabel.text);
//Edit: You need a cast in the above line of code:
NSLog(#"Button: %#", ((UIButton *)sender).titleLabel.text);
}
Then, you can use Interface Builder to connect to all of the buttons. You can have some sort of if/else logic to test which button was tapped.
You can check the titleLabel property, or you can assign an IBOutlet to each button and check for that.
For example:
if([sender isEqual:buttonOutlet1]){
//If this button is attached to buttonOutlet1
//do something
}
Alternatively, you can simply use the label of each button, not worrying about outlets.
A third option would be to generate and lay out the buttons in code, and then access them as elements of an array of buttons.
A fourth option would be to add tags to the buttons and check for the button's tag in your function.
Give each button a unique tag value. in the IBAction, sender.tag tells you which button was tapped.
The IBAction routine you set up to handle the button presses has a sender parameter. Examine that to decide.
-(IBAction) buttonPress: (id) sender {
UIButton *pressedButton = (UIButton *)sender;
NSString *buttonTitle = [pressedButton currentTitle];
if ([buttonTitle isEqualToString: #"SomeTitle"]) {
//do work for that button.
}
}
You can use a variety of NSString methods to compare or filter which button was pressed and handle it through if's or switches.
That's quite simple, but since you're new, here's an answer.
(According to Stanford cs193p course, 2010-2011 fall (that's what they did with the calculator app)) make a method that receives an argument, which is the UIButton.
for example:
- (IBAction) someMethodThatDoesSomething:(UIButton *)sender;
Then make if statements according to the sender.titleLabel.text
I don't know if there are any other solutions. Hope this helps!
-(IBAction)myButtonAction:(id)sender {
if ([sender tag] == 0) {
// do something here
}
if ([sender tag] == 1) {
// Do some think here
}
}
// in Other words
-(IBAction)myButtonAction:(id)sender {
NSLog(#"Button Tag is : %i",[sender tag]);
switch ([sender tag]) {
case 0:
// Do some think here
break;
case 1:
// Do some think here
break;
default:
NSLog(#"Default Message here");
break;
}

changing a button's text from another method when the buttons are in a subclass?

How do you access a button that's in a subview of a view?
I have a viewController 'GamePlay', which has a scrollview in it called 'gameScroll'. Within this scrollview I have about 100 buttons, each with a tag, and I want to be able to change the text of the button from another method.
- (void) viewDidLoad {
//Created buttons in a for-loop, assigning each a tag
//numOfButtons is total number of buttons created
}
I imagine it would be something like this? but I cant seem to find an answer on exactly how i do it when the button is in a subview
- (void) otherMethod {
for (int i=0; i<numOfButtons; i++) {
// tagsForAction = get list of buttons that need to be changed from another array
for (j=0; j<tagsForAction.length; j++) {
intTagForAction = [tagsForAction objectAtIndex:j];
if (i = tagForAction) {
UIButton* button = [Gameplay.gameScroll.view viewWithTag:tagForAction];
button.title = #"A";
}
}
}
}
I know this code isnt totally right. Im just giving you an idea of the process. I can do everything except this part in the if statement:
UIButton* button = [Gameplay.gameScroll.view viewWithTag:tagForAction];
button.title = #"A";
so how do I change the text of these buttons?
NSArray *subViewList = [gameScroll subviews];
for (id button in subViewList)
{
if ([button isKindOfClass:[UIButton class]])
{
[button setTitle:#"OK" forState:UIControlStateNormal];
}
}
Try this code
You don't have to use the for loop like that, you can get an array of subviews from any view by doing something like [someView subviews]. So, inside of your otherMethod function you can do something like:
for (UIView *v in [gameScroll subviews]) {
if (v.tag == <some_int_here>) {
[v setTitle:#"Some other title" forState:UIControlStateNormal];
}
}
I'm not exactly sure what your criteria is for determining which buttons inside the gameScroll view have to get updated, but you can work from here.

How to remove everything fron the superView and not just the last item?

In my app i had to draw certain checkboxes at a same time and i used a single function to add all of them. Now when a user clicks one of them all of those checkboxes should get removed from the superview and currently its just removing the last one. Also i have issue to recognize those checkboxes like which one is clicked. i know it should be done through Tag property but don't know how exactly it should be implemented.
Any suggestions.
Removing all subviews
int numberOfSubviews = [[yourView subviews] count];
for(int i=0;i<numberOfSubviews-1;i++
{
[[youView subviews]objectAtIndex:i]removeFromSuperView];
}
//this will leave check box that you added at last.... for first one to remain loop from 1 to numberOfSubviews....
Using tag property...
when you are creating checkbox objects use
checkBoxObject.tag = i;
//I am considering i as looop count which you are using in a loop
to add checkboxes.
then whenever you need a object of checkbox
[yourViewonwhichYouAddedCheckBox viewWithTag:<your tag >];
Thanks
For identifying a "checkbox" or better said any view within an action-method:
- (void)someActionHandler:(id)sender
{
UIView *actionOriginView = (UIView *)sender;
NSLog(#"this action came from view:%d", actionOriginView.tag);
}
For assigning the tag, you may use the IB or within your code, while instantiating;
UIView *myFunkyView = [[UIView alloc] initWithFrame:CGRectZero];
myFunkyView.tag = 1337;
For removing a bunch of views from your superview - lets assume their tag is set to 10 - 15;
for (int i=10;i <= 15;i++)
{
UIView *childView = [superview viewWithTag:i];
[childView removeFromSuperview];
}