0

Possible Duplicate:
Arguments in @selector

This is probably a really simple question, but I need a really good answer...

Using the following code I can call a method when a button is clicked...

[pushButton addTarget:self action:@selector(pushOrPull:andVI:) forControlEvents:UIControlEventTouchUpInside];
[pullButton addTarget:self action:@selector(pushOrPull:andVI:) forControlEvents:UIControlEventTouchUpInside];

The method is below...

-(void) pushOrPull: (int)pushPull andVI: (NSString *) videoId {

}

I want the buttons to be able to supply arguments to that method, but when I try this...

[pushButton addTarget:self action:@selector(pushOrPull:2 andVI:@"someVID") forControlEvents:UIControlEventTouchUpInside];
[pullButton addTarget:self action:@selector(pushOrPull:1 andVI:@"someVID") forControlEvents:UIControlEventTouchUpInside];

Xcode gives me two errors: "expected )"

How can I supply these two arguments to the method when my buttons get tapped?

Cœur
  • 37,241
  • 25
  • 195
  • 267
The Man
  • 1,462
  • 3
  • 23
  • 45
  • @Almo No that is not a duplicate buttons cannot be timed! I have no clue when the user will tap a button? – The Man Jul 17 '12 at 15:22
  • Selectors don't work like that :-) – Patrick Perini Jul 17 '12 at 15:23
  • Well is there any way that I can call a method (with arguments) on a button tap? – The Man Jul 17 '12 at 15:24
  • 1
    Does Shane's answer here (http://stackoverflow.com/questions/1018195/objective-c-calling-selectors-with-multiple-arguments) not solve your problem? – tarheel Jul 17 '12 at 15:26
  • You can't use the NSInvokation? That was the important part of the dupe; not the timer. If I have this wrong, then my apologies. – Almo Jul 17 '12 at 15:27
  • possible duplicates: [How can I send two arguments in a selector method?](http://stackoverflow.com/questions/1857817/how-can-i-send-two-arguments-in-a-selector-method?rq=1), [How to pass data through selector upon custom button click?](http://stackoverflow.com/questions/9918273/how-to-pass-data-through-selector-upon-custom-button-click?rq=1) – jscs Jul 17 '12 at 16:40

4 Answers4

1

Unfortunately, you can't. Buttons only "know how" to send themselves as the first argument. The best bet is to have the buttons "belong" to some view controller (to which they send their events) which can interpret the button press, and then call a delegate method elsewhere with as many arguments as you need.

To answer a related question, a "selector" never carries actual arguments, but it does carry one colon per argument: @selector(aMethodWithThis:andThat:)

Chris Trahey
  • 18,202
  • 1
  • 42
  • 55
1

What you could do is just have a method in the middle.

[pushButton addTarget:self action:@selector(runMyMethod) forControlEvents:UIControlEventTouchUpInside];
pushButton.tag =0;
[pullButton addTarget:self action:@selector(runMyMethod) forControlEvents:UIControlEventTouchUpInside];
pullbutton.tag =1;

-(void) runMyMethod:(id)sender {
    if(sender.tag ==0)
    {
       [self pushOrPull:1 andVI:@"someVID"];
    }
    else if (sender.tag ==1)
    {
       [self pushOrPull:2 andVI:@"someVID"];
    }
}
-(void) pushOrPull: (int)pushPull andVI: (NSString *) videoId {

}
glenn sayers
  • 2,414
  • 2
  • 17
  • 18
0

This is a bit better:

// set up an NSMutableDictionary, videoIDsForButtons as an iVar or property
[pushButton addTarget:self action:@selector(buttonWasPressed:) forControlEvents:UIControlEventTouchUpInside];
[videoIDsForButtons setObject: @"someVID" forKey: pushButton];

[pullButton addTarget:self action:@selector(buttonWasPressed:) forControlEvents:UIControlEventTouchUpInside];
[videoIDsForButtons setObject: @"someVID" forKey: pullButton];

 

- (void)buttonWasPressed:(id)sender
{
    if (sender == pushButton)
    {
        [self pushOrPull: 2 andVI: [videoIDsForButtons objectForKey: sender]];
    }
    else // assume pullButton
    {
        [self pushOrPull: 1 andVI: [videoIDsForButtons objectForKey: sender]];
    }
}

This is because selectors don't take arguments, only method calls do. And when a button is pressed, it supplies itself as the only argument (sender). You should have a whole separate responder method that looks at sender and determines the appropriate recourse.

Patrick Perini
  • 22,555
  • 12
  • 59
  • 88
0

unfortunately the -addTarget:action:forControlEvents: can call back you via the following method with the next parameters only:

-(IBAction)selector:(id)sender forEvent:(UIEvent *)event;

so, you should check inside this method which object fired the event (sender), and after it, still inside this method you can call your own -pushOrPull:andVI: method with the desired parameters, or you can set two different callback methods as well and then you won't have to check the sender parameter, just call your -pushOrPull:andVI: like this:

{
    // ...

    [pushButton addTarget:self action:@selector(pushButtonTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside];
    [pullButton addTarget:self action:@selector(pullButtonTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside];

    // ...

}

- (IBAction)pushButtonTouchedUpInside:(id)sender {
    [self pushOrPull:2 andVI:@"someVID"];
}

- (IBAction)pullButtonTouchedUpInside:(id)sender {
    [self pushOrPull:1 andVI:@"someVID"];
}
holex
  • 23,961
  • 7
  • 62
  • 76