按下按钮获取UITableView单元格行

时间:2011-09-21 18:00:55

标签: objective-c ios uitableview

我有一个显示一行单元格的tableview控制器。每个单元格有3个按钮。我已将每个单元格的标签编号为1,2,3。问题是我不知道如何找到按下按钮的单元格。我当前只在按下其中一个按钮时才收到发件人的标签。当按下按钮时,有没有办法获取单元格行号?

10 个答案:

答案 0 :(得分:278)

你应该真的使用这种方法:

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

Swift版本:

let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)

根据按下的按钮的位置,这将给你indexPath。如果您需要单元格,则只需拨打cellForRowAtIndexPath,或者如果需要行号,则拨打indexPath.row

如果您是偏执狂,可以在使用之前检查if (indexPath) ...,以防万一在表格视图中找不到indexPath

如果Apple决定更改视图结构,所有其他答案都可能会中断。

答案 1 :(得分:40)

编辑:这个答案已经过时了。 Please use this method instead


试试这个:

-(void)button1Tapped:(id)sender
{
    UIButton *senderButton = (UIButton *)sender;
    UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
    UITableView* table = (UITableView *)[buttonCell superview];
    NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
    NSInteger rowOfTheCell = [pathOfTheCell row];
    NSLog(@"rowofthecell %d", rowOfTheCell);
}

编辑:如果您使用的是contentView,请将其用于buttonCell:

UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;

答案 2 :(得分:17)

我建议这种方式来获取具有任何自定义子视图的单元格的indexPath - (与iOS 7兼容以及所有以前的版本

-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
//    UIView *parentCell = gestureRecognizer.view.superview;
    UIView *parentCell = sender.superview;

    while (![parentCell isKindOfClass:[UITableViewCell class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentCell = parentCell.superview;
    }

    UIView *parentView = parentCell.superview;

    while (![parentView isKindOfClass:[UITableView class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentView = parentView.superview;
    }


    UITableView *tableView = (UITableView *)parentView;
    NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];

    NSLog(@"indexPath = %@", indexPath);
}

这也不需要self.tablview

另外,请注意注释代码,如果您希望通过添加到自定义子视图中的@selector UIGestureRecognizer来使用相同的代码。

答案 3 :(得分:3)

有两种方法:

  1. @ H2CO3是对的。您可以执行@ user523234建议的操作,但只需稍加更改即可遵守应该位于UIButton和UITableViewCell之间的UITableViewCellContentView。所以要修改他的代码:

    - (IBAction)button1Tapped:(id)sender
    {
        UIButton *senderButton = (UIButton *)sender;
        UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview;
        UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview;
        UITableView* tableView = (UITableView *)tableViewCell.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    
  2. 如果您创建自定义UITableViewCell(您自己的子类),那么您只需在IBAction中调用self即可。您可以使用故事板或在设置单元格时以编程方式将IBAction功能链接到按钮。

    - (IBAction)button1Tapped:(id)sender
    {
        UITableView* tableView = (UITableView *)self.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    

答案 4 :(得分:2)

我假设您在cellForRowAtIndexPath中向单元格添加按钮,然后我要做的是创建自定义类子类UIButton,添加名为{{1}的标记在向单元格添加按钮时附加该数据。

答案 5 :(得分:2)

另一种简单的方法:

  • 获取tableView

  • 中的触摸点
  • 然后在点

  • 获取单元格的索引路径
  • 索引路径包含行索引

代码是:

- (void)buttonTapped:(id)sender {
    UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
    CGPoint point = [tap locationInView:theTableView];

    NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];

    NSInteger theRowIndex = theIndexPath.row;
    // do your stuff here
    // ...
}

答案 6 :(得分:1)

Swift 3

注意:这应该在accepted answer以上,除了meta frowns进行此类修改。

@IBAction func doSomething(_ sender: UIButton) {
   let buttonPosition = sender.convert(CGPoint(), to: tableView)
   let index = tableView.indexPathForRow(at: buttonPosition)
}

两条小评论:

  1. 默认函数的发件人类型为Any,没有转换。
  2. CGPointZero可以替换为CGPoint()

答案 7 :(得分:0)

一种解决方案可能是检查按钮的超级视图的标记,或者在视图层次结构中检查更高的标记(如果按钮位于单元格的内容视图中)。

答案 8 :(得分:0)

我想在swift中共享代码 -

extension UITableView
{
    func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
    {
        var view = view1;
        while view != nil {
            if (view?.isKindOfClass(UITableViewCell) == true)
            {
                return self.indexPathForCell(view as! UITableViewCell)!
            }
            else
            {
                view = view?.superview;
            }
        }
        return nil
    }
}

答案 9 :(得分:0)

在swift:

@IBAction func buttonAction(_ sender: UIButton) {
    guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
        return
    }
    // do something
}