Question

My iPhone app has many buttons and I want all the buttons to call the same method, but with different parameters.

For example I want tapping one button to call the method myMethod: with the argument @"foo", and a second button should call the same method but with argument @"bar".

Was it helpful?

Solution

The so called "IBActions" must have one of these signatures:

-(void)action;
-(void)actionWithSender:(id)sender;
-(void)actionWithSender:(id)sender event:(UIEvent*)event;

You cannot add any other parameters. Nevertheless you can use sender (which is button1 or button2 in your case) to get the parameter:

-(void)actionWithSender:(UIButton*)sender {
   NSString* parameter;
   if (sender.tag == 1)   // button1
     parameter = @"foo";
   else                   // button2
     parameter = @"bar";
   ...
}

OTHER TIPS

the real reason You cannot add additional parameter is that UIKIT will push params on the stack. so the only way is to use tags. A DIRTY way can be to convert a pointer to int and tagging the button with it:

myStruct params;
// fill params:
params.x=....
params.y=....
params.z=....


UIButton * btn = [UIButton......]; // create or use one from XIB
btn.tag = (int)&params;

... in Call back:
-(IBActions) doIt:(id)sender
{
  myStruct * paramsPtr = (myStruct*)tag;
  int i = paramsPtr->x;

NOTE: params MUST be keep static .. or allocate using malloc (more and more ugly code...). DO NOT use a local var: it will be allocated on stack so will be removed after exiting from the setup method.

Give your various UIButton instances different tag property values.

In your IBAction method -myMethod:, you might then do something like:

- (void) myMethod:(id)sender {
    switch (sender.tag) {
        case (firstButtonTag):
           doFooStuff;
           break;
        case (secondButtonTag):
           doBarStuff;
           break;
        // etc.
    }
}

The values firstButtonTag and secondButtonTag can be stored in an enum if you want to make this easy to maintain.

You can't pass parameters through an IBAction. What I usually do is give the buttons the unique tag in IB. THe tag is an integer value so I u then use a simple lookup table to convert the tag to some value.

In this case, three buttons but tags 1 to 3:

- (IBAction) buttonPressed: (UIButton*) sender
{
    static const NSString* names = { @"Foo", @"Bar", @"Baz" };
    id tag = [sender tag];
    if (tag >= 1 && tag <= 3) {
        NSLog(@"Button pressed is %@", names[tag]);
    }
}

(id)Sender is shows that whatever u pass on UIButton click event is directly pass to this method and no matter that what type it is , it take automatically like if you pass button tag then it take button tag as sender.tag etc

As others have mentioned you cannot pass your custom parameter into action method. If you do not like the solution using tags you may also subclass UIButton with your custom class and add your parameter there. (By I wouldn't bother and just use tags)

You don't. The only parameter is the sender object, which you may use to have a different behavior, but what I'd do is define 2 action methods, which simply in turn call the same method with a different parameter, i.e. you'd have:

- (IBAction)button1:(id)sender
{
    [self doStuff:kButton1];
}

- (IBAction)button2:(id)sender
{
    [self doStuff:kButton2];
}

- (void)doStuff:(ParamType)param;
{
    ...
}

In defense of that method (no pun intended), I'd add that it makes clearer when you review your UI with Interface Builder to see that different buttons actually have different effects, which is harder to tell if they all call whateverAction:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top