views:

1124

answers:

5

I currently have a UITableView that is populated with a custom UITableViewCell that is in a separate nib. In the cell, there are two buttons that are wired to actions in the custom cell class. When I click one of the buttons, I can call the proper method, but I need to know which row the button was pressed in. The tag property for each button is coming as 0. I don't need to know when the entire cell is selected, just when a particular button is pressed, so I need to know which row it is so I can update the proper object.

+6  A: 

You could use the tag property on the button to specify which row the button was created in, if you're not using tags for anything else.

pix0r
Do I need to set the tag in the cellForRowAtIndexPath method, and then access it when the button is pressed?
Tai Squared
Yes, that is the best method.
Jason
A: 

You can access the buttons superview to get the UITableViewCell that contains your button, but if you just need the row number, you can use the tag property like the previous post deacribes.

Marco Mustapic
Using [sender superview]; in the custom cell class (that contains the action methods for the buttons) gives me a UIView, not the cell. If I set the tag in the cellForRowAtIndexPath method, it still just comes as 0 for each button in the cell when pressed.
Tai Squared
+1  A: 

I have the same scenario. To achieve this, I derived a custom cell. I added two properties, section and row. I also added an owner, which would be my derived TableViewController class. When the cells are being asked for, I set the section/row based on the indexPath, along with the owner.

cell.section = indexPath.section cell.row = indexPath.row cell.owner = self

The next thing that I did was when I created the buttons, I associate the button events with the cell rather than with the tableViewController. The event handler can read the section and row entry and send the appropriate message (or event) to the TableViewController. This greatly simplifies house keeping and maintenance by leveraging existing methods and housekeeping and keeping the cell as self contained as possible. Since the system keeps track of cells already, why do it twice!

rklinkhammer
+1  A: 

Much easier solution is to define your button callback with (id)sender and use that to dig out the table row index. Here's some sample code:

- (IBAction)buttonWasPressed:(id)sender
{
    NSIndexPath *indexPath =
        [self.myTableView
         indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
    NSUInteger row = indexPath.row;

    // Do something with row index
}

Most likely you used that same row index to create/fill the cell, so it should be trivial to identify what your button should now do. No need to play with tags and try to keep them in order!

Clarification: if you currently use -(IBAction)buttonWasPressed; just redefine it as -(IBAction)buttonWasPressed:(id)sender; The additional callback argument is there, no need to do anything extra to get it. Also remember to reconnect your button to new callback in Interface Builder!

JOM
+1  A: 

Even easier:

-(IBAction) buttonPressed {
    NSIndexPath *myIndexPath = [(UITableView *)self.superview indexPathForCell: self];
    // do whatever you need to do with the information
}
William Jockusch