UITableViewCell中的两个button:如何确定select了哪个indexPath?
我想在每个表格视图单元格中放置两个button。 当我点击第一个button时,我希望应用程序显示一条警告消息:“您在indexpath:3,0点击button1”。 我的问题是:如何将button放在表格视图单元格中? 任何人都可以指导我?
以@ wedo的答案并简化它 – 你基本上需要两条信息:被点击的行和列号(“列”是button的顺序)。
解决scheme1 – 不是一个坏的解决scheme
这可以使用button.tag
和button.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的数量进行调整。