it-swarm.cn

按下按钮获取UITableView单元格行

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

84
minimalpop

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

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决定改变视图结构,那么所有其他答案都可能会破裂。

277
iwasrobbed

编辑:这个答案已经过时了。 请改用此方法


试试这个:

-(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;
40
user523234

我建议这种方式来获取具有任何自定义子视图的单元格的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

另外,请注意注释代码,如果您想通过添加到自定义子视图的UIGestureRecognizer的@selector来实现相同的代码。

17
Ashok

有两种方法:

  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);
    }
    
3
Mr. T

我假设您在cellForRowAtIndexPath中向单元格添加按钮,然后我要做的是创建一个自定义类子类UIButton,添加一个 标记 调用rowNumber,并在向单元格添加按钮时附加该数据。

2
Derek Li

另一个简单方法:

  • 在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
    // ...
}
2
vietstone

Swift 3

注意:这应该在 接受的答案 上面,除了 元皱眉 这样的编辑。

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

两条小评论:

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

我想在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
    }
}
0
Anupam Mishra

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

0
Jakob W

在Swift中:

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