Taking the @wedo answer and simplifying it a bit - you essentially need two pieces of information: the row number and the column that was used (the βcolumnβ is the order of the button).
Solution 1 is not a bad decision
This can be saved on the button using button.tag and button.titleLabel.tag . In -tableView:cellForRowAtIndexPath: you will do the following:
UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom]; button0.tag = indexPath.row; button0.titleLabel.tag = 0;
Your cellButtonAction: method will look like this:
- (IBAction)answerButtonAction:(UIButton *)sender { NSInteger row = sender.tag; NSInteger column = sender.titleLabel.tag;
Solution 2 is a much better solution.
The above works and everything is fine, but these are pretty hacks. Alternatively, it may take 3 minutes to subclass the button and add a property that can contain the values ββof rows and columns.
@interface IndexPathButton: UIButton
You would use this in the same way as the previous solution, but save the values ββin a custom property, not in tags. In tableView:cellForRowAtIndexPath:
// You'd create a button for each column here IndexPathButton *button0 = [IndexPathButton buttonWithType:UIButtonTypeCustom]; button0.indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:0]; [button0 addTarget:self action:@selector(cellButtonAction:) forControlEvents:UIControlEventTouchUpInside]; [cell.contentView addSubview:button0];
Solution 3 is the best solution.
UITableViewCells should typically use delegation for any heavy lifting that needs to be done. This pattern most closely matches the Apple delegation pattern for cells, for example. tableView:didSelectRowAtIndexPath and friends. So, let me create a base class, tableViewCell, which can be used to handle any number of controls and which should not go around indexPaths.
@protocol SOTableViewCellActionDelegate <NSObject> @required -(void)tableViewCell:(UITableViewCell *)cell didFireActionForSender:(id)sender; @end @interface SOActionCell : UITableViewCell @property (nonatomic, weak) id<SOTableViewCellActionDelegate> delegate; @end @implementation SOActionCell -(void)fireAction:(id)sender { [self.delegate tableViewCell:self didFireActionForSender:sender]; } @end
In -tableView:cellForRowAtIndexPath: you will do the following:
UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom]; button0.tag = 0; [button0 addTarget:cell action:@selector(fireAction:) forControlEvents:UIControlEventTouchUpInside]; [cell.contentView addSubview:button0];
Then we implement the required delegate method in tableViewController:
-(void)tableViewCell:(UITableViewCell *)cell didFireActionForSender:(id)sender { NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; NSAssert(indexPath, @"indexPath of cell shall always be found."]; if (!indexPath) return;