【问题标题】:Getting the exact location of a UITableViewCell获取 UITableViewCell 的确切位置
【发布时间】:2011-06-08 14:23:04
【问题描述】:

给定UITableView,如何找到特定UITableViewCell 的位置?换句话说,我希望它的框架相对于我的 iPhone 屏幕,而不是相对于UITableView。所以如果我的UITableView向上滚动,每个UITableViewCell的位置在屏幕上应该更高,等等。

【问题讨论】:

    标签: iphone ios uitableview


    【解决方案1】:

    您还可以使用rectForRowAtIndexPath 方法通过发送indexPath 来获取UITableView 的位置。

    - (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath
    

    所以使用如下:

    CGRect myRect = [tableView rectForRowAtIndexPath:indexPath];
    

    【讨论】:

    • 你在哪个函数中访问rectForRowAtIndexPath方法?
    • 在 didSelectRow... 方法中
    • @reising1: 一定不能崩溃,如果还是有同样的问题可以显示相关代码。
    【解决方案2】:

    除了 rectForRowAtIndexPath 你还需要考虑滚动。

    试试这个代码:

     // Get the cell rect and adjust it to consider scroll offset
     CGRect cellRect = [tableView rectForRowAtIndexPath:indexPath];
     cellRect = CGRectOffset(cellRect, -tableView.contentOffset.x, -tableView.contentOffset.y);
    

    【讨论】:

    • 这会产生单元格的屏幕坐标,+1 !
    • +1 用于考虑内容偏移。这会将单元格映射到其屏幕坐标。很好,谢谢。
    • 第二行可以简单点:cellRect = CGRectOffset(cellRect, -tableView.contentOffset.x, -tableView.contentOffset.y);
    • 如果您有任何(-tableView.contentOffset.y-tableView.contentInset.top),您可能还想减去 tableview 的 contentInsets
    • rectForRowAtIndex 将返回 UITableView 坐标系中的矩形。使用这里描述的convertRect 方法stackoverflow.com/questions/687793/… 将其转换为超级视图的坐标系,而不是手动摆弄偏移和插入。
    【解决方案3】:

    尝试以下操作(将 nil 作为 toView 参数发送意味着您要将矩形转换为窗口坐标):

    CGRect r = [cell convertRect:cell.frame toView:nil];
    

    请记住,如果特定行当前不可见,则可能没有 UITableViewCell 用于它 - 因此在使用该代码之前,您可能需要检查单元格是否有效(例如不是 nil)

    【讨论】:

    • 这会引发错误。程序终止。是的,单元格是可见的。
    • 错误信息是什么?以及如何获取单元格对象?
    【解决方案4】:

    斯威夫特 3

    相对于tableView:

    let rect = self.tableView.rectForRow(at: indexPath)
    

    相对于Screen:

    如果你只知道cell,

    if let indexPath = tableView.indexPath(for: cell) {
         let rect = self.tableView.rectForRow(at: indexPath)
         let rectInScreen = self.tableView.convert(rect, to: tableView.superview)
    }
    

    如果您知道indexPath,则无需调用if 语句。

    【讨论】:

      【解决方案5】:

      试试看 在

      didSelectRowAtIndexPath方法

      UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
      
      
              // get current location of selected cell
      
              CGRect rectInTableView = [tableView rectForRowAtIndexPath:indexPath];
      
              CGRect rectInSuperview = [tableView convertRect:rectInTableView toView:[tableView superview]];
      
      
               NSLog(@"Cell Y Is %f",rectInSuperview.origin.y);
      
              NSLog(@"Cell X Is %f",rectInSuperview.origin.x);
      

      【讨论】:

        【解决方案6】:

        Jhaliya 的回答对我来说还不够,我需要做更多的操作才能让它发挥作用。我的 tableView 被添加到 viewController 并且它的位置在屏幕的右半部分。因此,您需要将 tableView 原点作为滚动偏移量考虑在内。

        CGRect rowRect = [tableView rectForRowAtIndexPath:indexPath];
        CGPoint offsetPoint = [self.infoTableView contentOffset];
        
        // remove the offset from the rowRect
        rowRect.origin.y -= offsetPoint.y;
        
        // Move to the actual position of the tableView
        rowRect.origin.x += self.infoTableView.frame.origin.x;
        rowRect.origin.y += self.infoTableView.frame.origin.y;
        

        【讨论】:

          【解决方案7】:

          对于未来的观众,我无法为 UITableView 中的单元格获取可靠的框架。我试图在需要弹出框演示的 iPad 上以 ActionSheet 样式显示UIAlertController。最后,这种方法产生了最好的结果:

          // 44 is the standard height for a cell in a UITableView
          // path is the index path of the relevant row
          // controller is the UIAlertController
          CGRect frame = CGRectZero;
          frame.origin.y = 44 * path.row;
          frame.origin.x = table.frame.origin.x;
          frame.size = CGSizeMake(table.frame.size.width, 44);
          controller.popoverPresentationController.sourceRect = [tableView convertRect:frame toView:self.view];
          controller.popoverPresentationController.sourceView = self.view;
          

          【讨论】:

          • 我最终使用了您的答案。与其硬编码为 44,不如使用 cellForRowAtIndexPath,然后使用单元格的 bounds.height。
          【解决方案8】:

          Tomasz 和 Jhaliya 的 Swift 版本的答案,以防任何人(其他人)对此感到困惑:

          var cellRect = tableView.rectForRow(at: indexPath)
          cellRect = cellRect.offsetBy(dx: -tableView.contentOffset.x, dy: -tableView.contentOffset.y)
          

          【讨论】:

            【解决方案9】:

            如果您确实需要专门转换为窗口中的某个点,您可以这样做:

            [yourAppDelegate.window convertPoint:[cell.contentView.center] fromView:[cell.contentView]];
            

            我使用了单元格中心坐标,但你可以使用任何你想要的点。

            Vladimir 是对的,请注意不可见的行(或已被回收的行)。

            -S

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-20
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多