如何在定制的uitableViewCell中获取Button的indexPath?

时间:2010-03-18 07:36:09

标签: iphone

我创建了一个tableViewCell,包括一个图像,两个文本标签和一个uibutton。 该按钮被分配给一个动作方法(例如viewButtonPused:sender)。

我习惯用tableView处理行选择:didSelectRowAtIndexPath:所以我可以判断选择了哪一行。但是使用uibutton及其动作方法......我怎么知道呢?

提前致谢。

8 个答案:

答案 0 :(得分:17)

如果按钮的目标是UIViewController / UITableViewController或任何其他维护对UITableView实例的引用的对象,那么这样做很好:

- (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
}

使用此方法可以避免额外的实例变量,并且在有多个部分时可以正常工作。您需要有办法访问UITableView实例。

编辑:正如有人在下面的评论中指出的那样,这种方法在iOS 7中爆发了。如果您仍然对使用此方法而非感兴趣,请务必找到{{1}实例正确,即通过循环遍历超级视图,直到找到一个。

答案 1 :(得分:4)

在与Cell的原型相关联的类上定义委托。

// 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

现在转到要制作Cell委托的班级。这可能是UITableView的子类。在cellForRowAtIndexPath方法中,确保将Cell的委托分配给self。然后实现协议中指定的方法。

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

或者,如果您更喜欢基于块的方法:

// MyCell.h

typdef void(^CellButtonTappedBlock)(MyCell *cell);

@interface MyCell : UITableViewCell 
@property (nonatomic, copy) CellButtonTappedBlock buttonTappedBlock;
@end

然后在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
    }];

}

答案 2 :(得分:3)

我知道这是一个旧线程,但我发现这个方法最好,因为它没有superView调用(因此当Apple使用新的os版本更改视图层次结构时,它不受影响)并且不需要子类化或使用繁琐的标签,当细胞被重复使用时可能会搞砸。

- (void)buttonPressed:(UIButton *)sender {
    CGPoint location = [sender convertPoint:sender.center toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
    NSLog(@"%@", indexPath);
}

答案 3 :(得分:2)

- (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);
}

答案 4 :(得分:1)

如果您已直接在单元格上添加元素(您不应该这样做) -

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

如果您在单元格的contentView上添加了元素(这是建议的方式)

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

答案 5 :(得分:0)

int SelectedRow;中定义一个类变量didSelectRowAtIndexPath,就像赋值一样 SelectedRow = indexPath.row;

在您的操作方法viewButtonPused:sender

旁边使用此SelectedRow变量

答案 6 :(得分:0)

不是将按钮添加为单元格的子视图,而是将其设置为cell.accessoryView。 然后使用tableView:accessoryButtonTappedForRowWithIndexPath:来完成当用户点击此按钮时应该完成的事情。

答案 7 :(得分:0)

我现在使用的另一种方法是子类化UIButton并添加NSIndexPath类型的属性。 在cellForRowAtIndexPath上,我在action方法中分配indexPath的值及其可用。