Access UIButtons like buttonName+i - iphone

I'm trying to change the properties of various UIButton that I have declared as follows:
UIButton * button1; UIButton *
button2; ....
It's possible to access them in a similar way to this?
[button+i setTitle:#"button"
forState:UIControlStateNormal];
The variable "i" would be an integer to distinguish one from button from another.

you need to use the tag property of UIButton, which is an integer
EDIT to show tag property
UIButton* myButton .... // whichever way your button is init'd
// set the tag
myButton.tag = 2; // or i or whatever way you set it the property is an int
// get the tag
int y = myButton.tag; // set y to the tag value of the button
its that easy

Do you have lots and lots of button?
Okay, the immediate best way I can think of is something I have put into practice when I had something like 30+ buttons on a screen (it was a calendar).
I created an array into which I put the button then accessed them like this (or something like this)
for (UIButton* b in myBigArrayOfButtons) {
[b setTitle:#"button" for State:UIControlStateNormal];
}

Related

How To point to an object from string

My question is kind of general; in my project I have 10 UIButton objects
named Button1, Button2, Button3, Button4, Button5, Button6, Button7, Button8, Button9, and Button10
I also have UIImageview That are named exactly like the buttons from 1 to 10.
I want to write a code that will manipulate the image by the last character of the button (always a number from 1 to 10) and will affect the UIImageview the same way
Something like this
buttonlastcharacter = i;
if(sender.lastcharacternumber is:i){
Button%,i.frame = //Some manipulation
But basically all that I want is to have access to a certain object by string
How can I implement such a behavior?
There are a couple of better ways to do this. If these buttons are all static and in IB you can use an IBCollection array for image views and buttons to simply call them up by matching indexes.
Better yet just use the tag value for the buttons or image views.
It is maybe not the ideal solution in your case, but you can do it different ways:
using kvo
UIButton* myButton = [self valueForKey:[NSString stringWithFormat:#"button%i",i]];
or with selectors and properties
UIButton* myButton = [self performSelector:NSSelectorFromString([NSString stringWithFormat:#"button%i",i])];
Hm, you could use an array for your buttons and a tag for your UIImageView objects. They all inherit from UIView, which provides you with a .tag propterty. It is of type NSInteger* .
For convenience reasons I would suggest to name the buttons from 0 to 9. It does not really matter but the first index in the array would be 0 and therefore naming them accordingly just makes things easier.
Define
NSArray *buttonArray;
You may opt for NSMutableArray depending what else you may want to do with it.
In viewDidLoad code:
buttonArray = [NSArray arrayWithCapacity:10];
buttonArray[0] = button0;
..
buttonArray[9] = button9;
In your XIB file in Interface Builder, or whereever you may create the UIImages programmatically, add the tags accordingly.
image0.tag = 0;
...
image0.tag = 9;
assuming you name them image0 to image9.
In your appropriate action method code:
buttonArray[sender.tag] = someManipulation;
You can do it like this,
In your IBAction method:
- (IBAction)click:(id)sender
{
UIButton *but = (UIButton *)sender;
but.frame = your manipulation code;
}
or you can check the title like:
if([but.currentTitle isEqualToString:#"Button1])
{
//Manipulate button 1
}
if you have added tags for the buttons from 1-10 you can use,
if(but.tag == 2)
{
//Manipulate button 2
}

Is it possible to add a second tag to an UIbutton?

I was wondering if it is possible to add a second tag to a UIButton? I've created a number of buttons programatically in a for-loop and need a reference to the number of the button (e.g. 0, 1, 2) and another reference (integer) in which I store a reference to the page the button links to (e.g. 22, 30, 49). The numbers are not related so I can't determine the first through the second.
This is what I'd like to have:
for (int k=0; k < numberOfTabs; k++) // k < 4 (e.g. 3 < 4)
{
UIButton* btn = [[[UIButton alloc] initWithFrame:frame] autorelease];
btn.tag = k;
btn.tag2 = someReference;
btn.frame = CGRectMake(-10, 0, buttonWidth, buttonHeight);
[btn addTarget:self
action:#selector(tabAction:)
forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self
action:#selector(tabDelete:)
forControlEvents:UIControlEventTouchDragOutside];
/...
Any suggestions would be very much appreciated.
No you cant. Not directly at least. You can subclass UIButton and add another int property but that seems like an overkill for what you want..
I think it would be better to just decide on how you can fit both the values in the single tag integer...
e.g. if you have pageNumber and buttonNumber you can create the buttons tag like:
button.tag = pageNumber*100 + buttonNumber;
and when you want to which page a button belongs to or what is the index of a button on a page, you can dacode the tag:
int pageNum = button.tag /100;
int buttonNum = button.tag % 100;
Create a subclass of UIButton with your second tag declared as property.
You could as well create an array to map the tag of your button to a page, which would prevent creating a subclass but will introduce some array management method.
I'd prefer the array solution, as I try to prevent subclassing whenever I can.
Why not store the second (any more, if needed) parameters in something like an NSMutableArray?
NSMutableArray *button_to_page = [[NSMutableArray alloc] init];
...
for(...)
{
// Your button creation code
[button_to_page addObject:[NSNumber numberWithInt:my_button.tag];
}
You can get your page number at any time by simply indexing into the button_to_page array.
You can also search the array for a page number and get the button index (if needed).
Now, having said that, here you are creating a new NSNumber object for each button's page tag and also carrying around an NSMutableArray to boot. I really think that subclassing UIButton is the way to go. I don't like the idea of encoding stuff into the single tag unless there's a real compelling reason. If you subclass you are still keeping the UIButton pretty lightweight and all your data is encapsulated within the same object very cleanly:
MultiTag_UIButton.h
#import <Foundation/Foundation.h>
#interface MultiTag_UIButton : UIButton {
}
#property (nonatomic, assign) int page;
#end
MultiTag_UIButton.m
#import "MultiTag_UIButton.h"
#implementation MultiTag_UIButton
#synthesize page;
#end
It really is that simple, you don't have to write any code, just add the page property and you are off to the races. Then you can do this:
MultiTag_UIButton *test_button = [[MultiTag_UIButton alloc] init];
test_button.tag = 1;
test_button.page = 23;
NSLog(#"tag %i page %i", test_button.tag, test_button.page);
[test_button release];
Clean and simple. Realistically you'd have to do a little more in the new class, but you get the idea.
According to what I can see looking at Apple's documentation for UIView where the tag property is defined (since UIButton inherits from UIView), it appears you can only have the one.
There's nothing stopping you from subclassing UIButton to add another tag property if necessary as mentioned.
You could subclass, but then when you handle it (if you intermix it with non subclassed buttons), you are going to have to ask the object if it is is the new object type or implements the new accessor to get at it, which is a bit unpolymorphic.
What about if you just leave the class as is, but partition up the existing bits of the tag so that the lower 16 bits are for one purpose and the upper are for your other purpose? Nothing changes interface wise, you just do some masking on the .tag to get your values.

How to get the name of the button in an action?

I have a button named start and I want to know in the method that it calls what it's name is and I'm not really sure how to do it. This is the method the button calls.
-(IBAction) startMotion: (id)sender {
UIButton * buttonName = (UIButton *) sender;
NSLog(#"Button Name: %#", buttonName.currentTitle);
}
The NSLog prints
Button Name: (null)
You can set the title of the button through
[b setTitle:#"Start" forState:UIControlStateNormal];
and to get the title (currentTitle is read-only and may be nil):
[b currentTitle];
BTW, if you just want to differentiate multiple buttons, you can just set the tag property (an integer value) of the buttons.
Also, check if you have the button specified as an IBOutlet in your viewController class, and is it connected properly as an outlet in Interface Builder?
I would rather set a certain Tag and compare the tag value rather than reading the title of the button since you have possibility to localize your app where button titles will possibly be different.
I was using the wrong property in Interface Builder.I was using name property of button in Interface Builder instead of the title property from the button settings.

iphone sdk button tags?

I can't understand the logic og button tags. Can someone tell me how to use button tags?
For eg. There are two buttons on my view and I want to print something depending on their tags like:
if(button.tag==???)x{
}etc.
When you create the button, you can set it's tag.
myButton1.tag = 0;
myButton2.tag = 1;
Or if you're using interface builder, there's a field in the inspector to set the tag.
I assume you've linked the buttons to call the same action when they're pressed, or else you wouldn't be needing to distinguish by tag, so your method should look like:
- (IBAction)buttonPressed:(id)sender
{
UIButton *aButton = (UIButton *)sender; // we know the sender is a UIButton object, so cast it
if (aButton.tag == 0)
{
// button 1 pressed
}
else if (aButton.tag = 1)
{
// button 2 pressed
}
}
Yeah you can use the tag to retrieve the UIButtons, and apply the same logic with UIVIews (have a look at this method remembering that UIButton inherits from UIView).
Specifically where do you have problems? Can you post some code/pseudo-code of yours?

2D Array of UIButtons Isn't Working (Objective-C/iPhone development)

I've made a bunch of UIButtons in a grid and I want to be able to iterate over them easily so I've put them in an NSMutableArray.
Like so:
// in .h
UIButton* button1;
UIButton* button2;
...
UIButton* button9;
UIButton* myButtons[3][3];
// in init function in app
myButtons[0][0] = button1;
myButtons[0][1] = button2;
...
myButtons[2][2] = button9;
But now if I try to access the title of a button in myButtons I get nil:
// elsewhere in app
[button1 setTitle:#"A" forState:UIControlStateNormal];
// and then:
NSLog(#"currentTitle of button1: %#", (myButtons[0][0]).currentTitle); // -> (null)
Anybody know what's going on? Thanks!
first of all, that's not an NSMutableArray, it's just a plain ol' array.
Second, where do you set button1 to a non-null value? Is it before or after assigning myButtons[0][0] = button1;? I would check and make sure that myButtons[0][0] is non-null when calling the NSLog method. If it is, then you need to assign your array later or assign the buttons earlier.