views:

612

answers:

2

I created a table view that is populated with a custom UITableViewCell (like this). Each of the cells contains two UIButtons. I assign the action to the button like this:

 [decreaseButton addTarget:self action:@selector(decrease) forControlEvents:UIControlEventTouchUpInside];

Is this the right way? Anyway, it works, but in my "decrease" method I need to know in which of my 18 table view rows the button was pressed. indexPath.row doesn't work outside the cellForRowAtIndexPath method, of course. Can someone explain me how to do this?

Thanks a lot in advance!

iYassin

+2  A: 

You can do this in two ways.

Inspecting the Event Sender

Change your decrease method from:

- (void)decrease;

to:

- (void)decrease:(id)sender;

That way when decrease is called, you'll be given a reference to the button that had the touch up inside event.

Define the decrease Method Closer to the Information

Another solution would be to have a different target instance for each button (for example, implement the decrease function as part of the custom cell). That way you know the button that was touched was the one for the current cell.

Ben S
What kind of reference/which data type is this reference? I just tried to print it to the console with NSLog, but this made my app close instantly after clicking the button. In general, my question is the following: How can I use it in my method? ;-)
Yassin
The `sender` parameter is the instance of the button that had the event. So you would have to somehow look-up which cell has that button. Kind of annoying and requires extra state information. I would move the decrease function to the Cell class. That way you don't have to determine anything, you'll already be in the right place and know what button was pressed.
Ben S
What do you mean with "move the decrease function to the Cell class"?
Yassin
//Update: Just got it working with -(void)decrease:(id)sender and then accessing the tag. Thanks a lot!
Yassin
+1  A: 

The way i solved this is I keep track of data i might need inside my custom cell object. And the button is connected not to the external receiver but the cell it's self which in-turn knows how to call the real receiver of the action.

I make my cell with something like:

cell = [[MyTableViewCell alloc] initWithStyle:style 
                              reuseIdentifier:CellIdentifier];

And I have a setup method so i can re-init a cell when I dequeue it:

[cell setupMyCellWithContext:objectID 
                      target:[[UIApplication sharedApplication] delegate] 
                      action:@selector(someAction)];

so inside your cell class you use the action and target that was sent in the setup method to call the true target:

- (void)doAction:(id)sender {
 if ([target respondsToSelector:action]) {
     [target performSelector:action withObject:objectID afterDelay:0];
    }
}

So when your user taps the button, the os calls [cell doAction:], which calls the target and action selector you set up before hand with the correct context object.

deoryp