UITableViewCell中的两个button:如何确定select了哪个indexPath?

我想在每个表格视图单元格中放置两个button。 当我点击第一个button时,我希望应用程序显示一条警告消息:“您在indexpath:3,0点击button1”。 我的问题是:如何将button放在表格视图单元格中? 任何人都可以指导我?

以@ wedo的答案并简化它 – 你基本上需要两条信息:被点击的行和列号(“列”是button的顺序)。


解决scheme1 ​​ – 不是一个坏的解决scheme

这可以使用button.tagbutton.titleLabel.tag存储在button上。 在-tableView:cellForRowAtIndexPath:你会这样做:

 UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom]; button0.tag = indexPath.row; button0.titleLabel.tag = 0; // button #0 (or column 0) [button0 addTarget:self action:@selector(cellButtonAction:) forControlEvents:UIControlEventTouchUpInside]; [cell.contentView addSubview:button0]; 

你的cellButtonAction:方法看起来像这样:

 - (IBAction)answerButtonAction:(UIButton *)sender { NSInteger row = sender.tag; NSInteger column = sender.titleLabel.tag; // do something } 

解决scheme2 – 一个更好的解决scheme

上面的作品很好,但是相当不好听。 或者,可能需要3分钟的时间才能inheritancebutton并添加一个可以保存行和列值的属性。

 @interface IndexPathButton: UIButton // NSIndexPath provides a convenient way to store an integer pair // Note we are using cellIndex.section to store the column (or button #) @property (strong, nonatomic) NSIndexPath *cellIndex; @end @implementation IndexPathButton @end 

您可以像以前的解决scheme一样使用它,但将值存储在自定义属性中而不是标签中。 在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]; 

解决scheme3 – 最佳解决scheme

UITableViewCells通常应该使用委托进行任何繁重的工作。 这个模式最接近苹果自己的单元格委托模式,比如tableView:didSelectRowAtIndexPath和好友。 所以,我们来创build一个tableViewCell基类,它可以用来处理任何数量的控件,而不需要传递indexPaths。

 /** Simple protocol to allow a cell to fire any type of action from a control. */ @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 

-tableView:cellForRowAtIndexPath:你会这样做:

 UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom]; button0.tag = 0; [button0 addTarget:cell action:@selector(fireAction:) forControlEvents:UIControlEventTouchUpInside]; [cell.contentView addSubview:button0]; 

然后在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; // do whatever you want to do with your button action here // using indexPath, sender tag, button title, etc. } 

当你在UITableCell中只有一个button时,使用indexPath作为标记值是可以的,但是如果你想跟踪更多的话,可以使用模运算符:

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath { ... imageButton1.tag=indexPath.row*2; [imageButton1 addTarget:self action:@selector(buttonPushed:) [cell.contentView addSubview:imageButton]; ... imageButton2.tag=indexPath.row*2+1; [imageButton2 addTarget:self action:@selector(buttonPushed:) [cell.contentView addSubview:imageButton]; 

对于select器,你可以区分button,并得到像这样的indexPath:

 -(void) buttonPushed:(id)sender{ UIButton *button = (UIButton *)sender; switch (button.tag%2) { case 0: // imageButton1 is pressed // to reach indexPath of the cell where the button exists you can use: // ((button.tag-button.tag%2)/2) break; case 1: // imageButton2 is pressed break; } 

这个例子是2个button,但你可以根据button的数量进行调整。