【问题标题】:Getting row of UITableView cell on button press按下按钮时获取 UITableView 单元格的行
【发布时间】:2011-11-22 04:42:35
【问题描述】:

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

【问题讨论】:

    标签: objective-c ios uitableview


    【解决方案1】:

    迅速:

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

    【讨论】:

      【解决方案2】:

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

      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 决定更改视图结构,所有其他答案都可能会中断。

      【讨论】:

      • 这个,一百万次。 没有其他方法有效,但这是完美的,也是迄今为止最简单的解决方案
      • 这个答案有效,因为它是正确的解决方案。其他的是变通方法。谢谢!
      • 如果你没有self.tableview,请参考我在这个页面上的回答。
      • 一旦我意识到我的发件人是错误的班级,这对我有用。将其修复为按下的 UIButton,现在它可以工作了!
      • 只要记住方法是convertPoint:*to*View 而不是convertPoint:*from*View。我使用 Xcode 自动完成并最终使用 fromView 方法导致无法正常工作......
      【解决方案3】:

      斯威夫特 3

      注意:这确实应该放在上面的accepted answer 中,除了meta frowns 进行此类编辑。

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

      两个小cmets:

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

      【讨论】:

      • 完美运行。
      【解决方案4】:

      我想快速分享代码 -

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

      【讨论】:

        【解决方案5】:

        另一种简单的方法:

        • 在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】:

          我会推荐这种方式来获取具有任何自定义子视图的单元格的 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 来获得相同的注释代码。

          【讨论】:

          • 如果我需要在 uitableviewcontroller 中找到数据怎么办?
          • 好答案。如果您有一个搜索栏并且想知道当前使用的是哪个表,您也可以使用它。
          • 表格单元格层次结构改变了吗?你能帮我了解发生了什么变化吗?是否可以进一步改变?
          【解决方案7】:

          编辑:此答案已过时。 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;
          

          【讨论】:

          • 您不应该将子视图添加到单元格本身,而只能添加到其contentView 属性 - 所以这个解决方案并不真正起作用。
          • 我同意@H2CO3,我也不认为这应该通过引用超级视图来完成。请在下面查看更好的方法:stackoverflow.com/a/16270198/308315
          • @minimalpop 你能改一下正确答案吗?有一个更好的问答!
          • 这在 iOS 7 中不起作用。使用 indexPathForRowAtPoint:在下面回答
          • 我用 UICollectionView 尝试了相同的版本,并且效果很好。非常感谢!
          【解决方案8】:

          有两种方式:

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

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

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

              【讨论】:

              • 这很好,但没有理由为它创建UIButton 的子类。 tagUIView 的公共属性。
              • 不知道我在想什么,并假设 UI 不是 UI,谢谢指正!
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-11-19
              • 1970-01-01
              • 2015-02-10
              • 1970-01-01
              相关资源
              最近更新 更多