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

时间:2017-02-27 02:13:02

标签: objective-c macos uitableview cocoa

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

我知道如何获取行ID和行的位置相对于整个NSTableView,但我需要在可见视图中获取位置...

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

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

提前致谢。

1 个答案:

答案 0 :(得分:6)

“可见视图”(很多视图可见)或“视图”(行视图?表视图?滚动视图)的含义尚不清楚。我想你想要相对于滚动视图几何的行的边界矩形。

每个视图都定义了子视图放置的几何体(坐标系)。子视图的frame位于其超视图的几何中。如果更改超级视图的几何图形,则在屏幕上,子视图似乎会移动。这是滚动视图的工作方式。

NSScrollView不会更改自己的几何图形来滚动文档(在您的情况下,表格中)。 (请注意,这与iOS不同,其中UIScrollView 更改自己的几何体以进行滚动。)NSScrollView具有滚动条和NSClipView子视图(其中它混淆地调用它的contentView),剪辑视图将文档视图(您的表视图)作为其子视图:

+ 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
          |
          ...

如果表视图有5000行,表视图的rowHeight是17(默认值),而表视图的intercellSpacing.height是2(默认值),那么表视图的{{1将为5000 *(17 + 2)= 95000.行号frame.size.height的行视图的frame.origin.yi。行视图0的19 * i为0,行视图4999的frame.origin.y为94981.但是这些y坐标不一定与行相对于滚动视图或封闭窗口的位置或者屏幕!

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

因此,您可以通过询问表视图来获取包围行的矩形,例如:

contentView.bounds.origin.y

CGRect tableViewRowRect = [self.tableView rectOfRow:1500]; 返回的矩形位于表格视图的几何图形中;它是相对于表视图的原点,如果表视图已滚动,可能远离屏幕。

如果您希望行的矩形相对于滚动视图,请将其转换为:

-[NSTableView rectOfRow:]

如果您希望行的矩形相对于封闭窗口的内容视图,您可以转换为该视图:

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

如果您想在窗口的基本坐标系中使用矩形(例如,与鼠标事件的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