ios 按下按钮时获取 UITableView 单元格的行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7504421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:35:34  来源:igfitidea点击:

Getting row of UITableView cell on button press

objective-ciosuitableview

提问by minimalpop

I have a tableview controller that displays a row of cells. Each cell has 3 buttons. I have numbered the tags for each cell to be 1,2,3. The problem is I don't know how to find on which cell a button is being pressed. I'm currently only getting the sender's tag when one of the buttons has been pressed. Is there a way to get the cell row number as well when a button is pressed?

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

回答by iwasrobbed

You should really be using this method instead:

你真的应该改用这个方法:

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

Swift version:

迅捷版:

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

That will give you the indexPathbased on the position of the button that was pressed. Then you'd just call cellForRowAtIndexPathif you need the cell or indexPath.rowif you need the row number.

这将indexPath根据按下的按钮的位置为您提供。然后,cellForRowAtIndexPath如果您需要单元格或indexPath.row需要行号,您只需拨打电话。

If you're paranoid, you can check for if (indexPath) ...before using it just in case the indexPathisn't found for that point on the table view.

如果您是偏执狂,您可以if (indexPath) ...在使用它之前进行检查,以防万一indexPath在表视图上找不到该点。

All of the other answers are likely to break if Apple decides to change the view structure.

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

回答by user523234

Edit: This answer is outdated. Please use this method instead

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



Try this:

尝试这个:

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

Edit: If you are using contentView, use this for buttonCell instead:

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

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

回答by Ashok

I would recommend this way to fetch indexPath of cell which has any custom subview - (compatible with iOS 7 as well as all previous versions)

我会推荐这种方式来获取具有任何自定义子视图的单元格的 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);
}

This doesn't require self.tablvieweither.

这也不需要self.tablview

Also, notice the commented code which is useful if you want the same through a @selector of UIGestureRecognizer added to your custom subview.

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

回答by Mr. T

There are two ways:

有两种方式:

  1. @H2CO3 is right. You can do what @user523234 suggested, but with a small change, to respect the UITableViewCellContentView that should come in between the UIButton and the UITableViewCell. So to modify his code:

    - (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. If you create a custom UITableViewCell (your own subclass), then you can simply call selfin the IBAction. You can link the IBAction function to your button by using storyboard or programmatically when you set up the cell.

    - (IBAction)button1Tapped:(id)sender
    {
        UITableView* tableView = (UITableView *)self.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    
  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(您自己的子类),那么您可以简单地调用selfIBAction。您可以在设置单元格时使用情节提要或以编程方式将 IBAction 函数链接到您的按钮。

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

回答by Derek Li

I assume you add buttons to cell in cellForRowAtIndexPath, then what I would do is to create a custom class subclass UIButton, add a tagcalled rowNumber, and append that data while you adding button to cell.

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

回答by vietstone

Another simple way:

另一种简单的方法:

  • Get the point of touch in tableView

  • Then get index path of cell at point

  • The index path contains row index

  • 在 tableView 中获取触摸点

  • 然后在点获取单元格的索引路径

  • 索引路径包含行索引

The code is:

代码是:

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

回答by Roy Falk

Swift 3

斯威夫特 3

Note: This should really go in the accepted answerabove, except that meta frownsupon such edits.

注意:这应该真正出现在上面接受的答案中,除了元不赞成这样的编辑。

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

Two minor comments:

两个小意见:

  1. The default function has sender type as Any, which doesn't have convert.
  2. CGPointZero can be replaced by CGPoint()
  1. 默认函数的发送者类型为 Any,没有转换。
  2. CGPointZero 可以替换为 CGPoint()

回答by Leszek Szary

In swift:

迅速:

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

回答by Anupam Mishra

I would like to share code in 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
    }
}

回答by Jakob W

One solution could be to check the tag of the button's superview or even higher in the view hierarchy (if the button is in the cell's content view).

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