How to pass in a a parameter on a button click in Objective C?
So I 开发者_StackOverflow中文版am trying pass in parameters to my "buttonClicked" function so that I can dynamically control what happens when you click the button. Every way that I try to do it on my own just breaks my code. I have searched many different sites and answers on stackOverflow, but I can't seem to find an answer. I am fairly new to objective C, especially with functions, So I could really use some help figuring out how to do this. Thanks in advance
Here is my code thus far and what I am trying to do:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
NSLog(@"Hi 1!");
[button addTarget:self action:@selector(buttonClicked:buttonType:buttonID:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(buttonViewXvalue, buttonViewYvalue, buttonViewWidth, buttonViewLength);
[self.view addSubview:button];
Then the Declaration in the Header File:
- (IBAction)buttonClicked:(id)sender theButtonType: (int)buttonType: theButtonID: (int) buttonID;
and the implementation:
- (IBAction)buttonClicked:(id)sender theButtonType: (int)buttonType: theButtonID: (int) buttonID
{
//Here I would use the buttonType and buttonID to create a new view.
NSLog(@"Hi!");
}
You can't use multi-parameter methods with addTarget:action:forControlEvents:
. Instead you might set the button's tag
, then look up information later based on the tag.
The action you add to UIButton (or any UIControl for that matter) must have a signature like (void)actionName
or (void)actionName:(id)sender;
as defined by target-action design pattern.
That gives you two simple solutions. One is that each of your buttons calls different (void)actionName
-like method, which then calls a more complex method on self and passes the required parameters. Other way is to give each of your buttons a tag property and have them call (void)actionName:(id)sender
-like method (they can all call the same one) and then you call the right method with right parameters depending on this tag:
- (void)actionName:(UIButton)sender;
{
if (sender.tag == 1) {
[self firstMethodWithString:someString andNumber:someNumber];
} else if (sender.tag == 2) {
[self secondMethodWithArray:someArray dictionary:someDictionary andColor:someColor];
} // and so on
}
Notice how I changed sender from id to UIButton here. This enables you to call tag without casting and not get a compiler warning, because compiler know you only expect UIButton instances to call this method.
If you really wanted to you could create a separate callback for each button, like:
// In your Whatever.h file
- (IBOutlet)actionButton1:(UIButton *)sender;
- (IBOutlet)actionButton2:(UIButton *)sender;
// In your Whatever.m file
- (IBOutlet)actionButton1:(UIButton *)sender
{
// do button 1 specific stuff
}
- (IBOutlet)actionButton2:(UIButton *)sender
{
// do button 2 specific stuff
}
// etc you get the idea
Then from Interface Builder look at your Whatever.xib file. You can link the "Sent Event" (drag from right side column) of "Touch Up Inside" to any of those actions above which will pop up in "File's Owner" (left column, when you release drag). You can do a different one for each button.
I should mention that generally if these are variants of the same functionality it makes more sense to use the tag property of UIButton.
I have solved this problem with an array of objects: all the parameters are stored in one object, then the object is inserted in the array, finally, the index of the object in the array is passed in the TAG property of the button. This technique works for one or many buttons. I did it for an app that had a list of contacts, where you were able to accept or reject them with buttons, and this buttons were calling the same action method, thanks to the TAG it was possible to know what parameters send to database. Steps:
1- Create a new class : New File, Objective-C class, name it, subclass of NSOBJECT, save it.
2- In the header of this new class declare one property for each parameter.
3- Now go to the IMPLEMENTATION file of the class of the viewcontroller where your button belongs to.
4- Import your new class : #import "new_class.h"
5- Declare the array in the INTERFACE section :
@interface my_viewcontroller ()
{ NSMutableArray * my_array; }
6- In the VIEWDIDLOAD method create the array as empty :
my_array = [ [ NSMutableArray alloc ] initWithObjects : nil ];
7- In the method where you get the data for the parameters, declare an object of the new class, instantiate it and fill the properties :
new_class * nc;
nc = [ [ new_class alloc ] init ];
nc.param1 = @"abc";
nc.param2 = 123;
nc.param3 = true;
8- Now insert it in the array :
[ my_array addObject : nc ];
9- Store the value 0 in the TAG of the button. You will use this value as index to access the parameters in the my_array[ 0 ] position.
If there are more buttons, for example, from a web service that returns JSON data, just loop through the data creating more instances of the new class and inserting them in the array. Later, for example, in a tableview with dynamic cells and a template cell with buttons, in the method CELLFORROWATINDEXPATH, you will be able to store the INDEXPATH value in the TAG of every button, so these buttons will access their own parameters.
精彩评论