我想在每个表格视图单元格中放置两个按钮。当我点击第一个按钮时,我希望应用程序显示一条警告消息:“您在indexpath点击了button1:3,0”。我的问题是:如何将按钮放在表格视图单元格中?谁能指导我?
答案 0 :(得分:7)
采用@ wedo的答案并简化它 - 你基本上需要两条信息:被点击的行和列号(“列”是按钮的顺序)。
可以使用button.tag
和button.titleLabel.tag
将其存储在按钮上。在-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
}
以上作品并没关系,但它相当hacky。或者,将按钮子类化并添加一个可以保存行和列值的属性可能需要3分钟。
@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
您可以像以前的解决方案一样使用它,但是将值存储在自定义属性而不是标记中。在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];
UITableViewCells
通常应该使用委托进行任何需要完成的繁重任务。这种模式最接近苹果自己的细胞代表模式,例如tableView:didSelectRowAtIndexPath
和朋友们。所以,让我们创建一个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.
}
答案 1 :(得分:5)
当您在UITableCell中只有一个按钮时,使用 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];
对于选择器,您可以区分按钮并获取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个按钮,但您可以根据按钮数量进行调整。