How can I get the indexPath of a UIButton in a custom tableViewCell?

I created a tableViewCell, including an image, two text labels and a uibutton. A button is assigned to an action method (for example, viewButtonPused: sender).

I use to handle row selection using tableView: didSelectRowAtIndexPath: so I could determine which row was selected. But with uibutton and its action method .... How can I say?

Thanks in advance.

+4
source share
8 answers

Define a delegate in the class associated with the Cell prototype.

//MyCell.h

@protocol MyCellDelegate - (void)buttonTappedOnCell:(MyCell *)cell; @end @interface MyCell : UITableViewCell @property (nonatomic, weak) id <MyCellDelegate> delegate; @end 

//MyCell.m

 @implementation MyCell - (void)buttonTapped:(id)sender { [self.delegate buttonTappedOnCell:self]; } } @end 

Now go to the class you want to make the Cell delegate. This will probably be a subclass of UITableView. In the cellForRowAtIndexPath method, make sure you assign a Cell delegate to yourself. Then we implement the method specified in the protocol.

 - (void)buttonTappedOnCell:(MyCell *)cell { NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; int row = indexPath.row; } 

Or, if you prefer a block-based approach:

//MyCell.h

 typdef void(^CellButtonTappedBlock)(MyCell *cell); @interface MyCell : UITableViewCell @property (nonatomic, copy) CellButtonTappedBlock buttonTappedBlock; @end 

Then in your tableView dataSource:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MyCell *cell = .... __weak typeof(self) weakSelf = self; [cell setButtonTappedBlock:^(MyCell *cell) { NSIndexPath *indexPath = [weakSelf.tableView indexPathForCell:cell]; // Do stuff with the indexPath }]; } 
+4
source

If the goal of the button is a UIViewController / UITableViewController or any other object that supports a reference to an instance of a UITableView , this will be nice:

 - (void)viewButtonPushed:(id)sender { UIButton *button = (UIButton *)sender; UITableViewCell *cell = button.superview; // adjust according to your UITableViewCell-subclass' view hierarchy NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; // use your NSIndexPath here } 

Using this approach will allow you to avoid additional instance variables and will work fine if you have several partitions. However, you need to have access to the UITableView instance.

Edit: as indicated in the comments below, this approach violated iOS 7. If you are still interested in using this approach by tags, be sure to find the UITableViewCell instance correctly, i.e. going through supervisors until you find them.

+17
source

I know this is an old thread, but I find this method best since it is free of superView calls (and therefore when Apple changes the view hierarchy with new versions of os, it remains unaffected) and does not require subclassing or using bulky tags, which can be damaged when the cell is reused.

 - (void)buttonPressed:(UIButton *)sender { CGPoint location = [sender convertPoint:sender.center toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location]; NSLog(@"%@", indexPath); } 
+3
source
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... [cell.customCellButton addTarget:self action:@selector(customCellButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; [cell.customCellButton setTag:indexPath.row]; } - (void)customCellButtonTapped:(id)sender { UIButton *button = (UIButton *)sender; NSLog(@"indexPath.row: %d", button.tag); } 
+2
source

If you have directly added elements in the cell itself (which you should not) -

 NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview] ]; 

If you added elements to the cell’s contentView (which is the suggested way)

 NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview] ]; 
+1
source

define one variable of the class int SelectedRow; inside didSelectRowAtIndexPath assign a value to it as SelectedRow = indexPath.row;

use this SelectedRow variable from your viewButtonPused:sender action method

0
source

Instead of adding a button as a subset of the cell, set cell.accessoryView . Then use tableView:accessoryButtonTappedForRowWithIndexPath: to do your things, which should be done when the user removes this button.

0
source

Another way I'm using now is to subclass UIButton and add a property of type NSIndexPath. In cellForRowAtIndexPath I assign the value to indexPath and its accessible by the action method.

0
source

Source: https://habr.com/ru/post/1304438/


All Articles