objective-c - 从可见的 tableView 中获取行的位置,而不是整个 tableView

标签 objective-c macos uitableview cocoa

简单地说 - 我有一个包含很多行的 NSTableView。只有大约 20 个是可见的,其余的只能通过滚动才能看到。

我知道如何获取行 id 以及行相对于整个 NSTableView 的位置,但我需要获取可见 View 中的位置...

也就是说,如果第 1500 行位于可见 View 中,我需要它相对于该 View 的 y 坐标,而不是相对于整个行列表的 y 坐标。

我自己似乎无法解决这个问题......

提前致谢。

最佳答案

不清楚“可见 View ”(许多 View 可见)或“该 View ”(行 View ?表格 View ? ScrollView )的含义。我猜你想要的是行的边界矩形,相对于 ScrollView 的几何形状。

每个 View 都定义一个几何图形(坐标系)来放置其 subview 。 subview 的frame位于其父 View 的几何结构中。如果更改 super View 的几何形状,则在屏幕上, subview 会出现移动。这就是 ScrollView 的工作原理。

NSScrollView不会更改其自身的几何形状来滚动文档(在您的情况下为表格)。 (请注意,这与 iOS 不同,UIScrollView 确实更改其自己的滚动几何形状。)NSScrollView有滚动条和 NSClipView subview (它被混淆地称为 contentView ),并且剪辑 View 将文档 View (您的表格 View )作为其 subview :

+ NSScrollView
  |
  +-- NSScroller (the scroll view's horizontalScroller)
  |
  +-- NSScroller (the scroll view's verticalScroller)
  |
  +-- NSClipView (the scroll view's contentView)
      |
      +-- NSTableView (the scroll view's documentView, but not a direct subview of it)
          |
          +-- NSTableRowView
          |
          +-- NSTableRowView
          |
          +-- NSTableRowView
          |
          +-- NSTableRowView
          |
          ...

如果 TableView 有 5000 行,并且 TableView 的 rowHeight是 17(默认值), TableView 的 intercellSpacing.height是 2(默认值),那么 TableView 的 frame.size.height将为 5000 * (17+2) = 95000。frame.origin.y行号 i 的行 View 的是 19 * i 。行 View 0 frame.origin.y是 0 且行 View 4999 的 frame.origin.y是 94981。但是这些 y 坐标不一定与行相对于 ScrollView 或封闭窗口或屏幕的显示位置有任何关系!

要滚动表格, ScrollView 通过设置剪辑 View 的 bounds.origin 来调整其剪辑 View 的几何形状。 。请记住, ScrollView 的 contentView属性指向剪辑 View 。要水平滚动, ScrollView 会更改 contentView.bounds.origin.x ,并且要垂直滚动, ScrollView 会更改 contentView.bounds.origin.y 。这具有相对于 ScrollView 、封闭窗口和屏幕移动 TableView (及其所有 subview )的效果。

因此,您可以通过询问 TableView 来获取包围一行的矩形,例如如下所示:

CGRect tableViewRowRect = [self.tableView rectOfRow:1500];

-[NSTableView rectOfRow:] 返回的矩形位于表格 View 的几何形状中;它是相对于表格 View 的原点而言的,该原点(如果表格 View 已滚动)可能远离屏幕。

如果您想要相对于 ScrollView 的行矩形,请像这样转换:

NSScrollView *scrollView = self.tableView.enclosingScrollView;
CGRect scrollViewRowRect = [self.tableView convertRect:tableViewRowRect
    toView:scrollView];

如果您想要相对于封闭窗口的内容 View 的行矩形,您可以转换为该 View :

NSView *rootView = self.tableView.window.contentView;
CGRect rootViewRowRect = [self.tableView convertRect:tableViewRowRect
    toView:rootView];

如果您希望矩形位于窗口的基本坐标系中(例如,与鼠标事件的 locationInWindow 进行比较),您也可以这样做:

CGRect windowRowRect = [self.tableView convertRect:tableViewRowRect
    toView:nil];

如果你想要 NSScreen 中的矩形坐标(例如,与窗口的 frame 进行比较),您甚至可以这样做:

NSWindow *window = self.tableView.window;
CGRect screenRowRect = [window convertRectToScreen:windowRowRect];

关于objective-c - 从可见的 tableView 中获取行的位置,而不是整个 tableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42476779/

相关文章:

ios - 如何在 iOS/OS X 上使用ripemd128进行散列?

ios - 如何为 UITableViewHeaderFooterView 设置 textAlignment?

iPhone UINavigationBar 向上/向下移动

ios - 在 tableView.deselectRowAtIndexPath 中使用 indexPath 与 indexPath.row

objective-c - NSManagedObjectContext 具有不同的进程

python - 如何使用 Python 从任何目录启动脚本

macos - linux中~directory_name和/directory_name有什么区别

ios - 如何在 Internet 上为 iOS 应用程序存储数据

php - Objective-c NSArray 的 array_key_exists() 和 array_search() 等价物是什么?

ios - 当我用 Obj-C 初始化时,可变的 Swift 数组变成 NSArray