按下按钮获取UITableView单元格行

问题描述 投票:84回答:10

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

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


0
投票

在快速:

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

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;

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

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


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

2
投票

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


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

1
投票

斯威夫特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()

0
投票

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


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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.