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

jul*_*ian 1 macos cocoa objective-c uitableview

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

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

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

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

提前致谢.

rob*_*off 7

目前还不清楚"可见视图"(很多视图是可见的)或"视图"(行视图?表视图?滚动视图)的含义.我想你想要相对于滚动视图的几何形状的行的边界矩形.

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

An 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
          |
          ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

CGRect tableViewRowRect = [self.tableView rectOfRow:1500];
Run Code Online (Sandbox Code Playgroud)

返回的矩形-[NSTableView rectOfRow:]位于表视图的几何中; 它是相对于表视图的原点,(如果表视图已滚动)可能远离屏幕.

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

NSScrollView *scrollView = self.tableView.enclosingScrollView;
CGRect scrollViewRowRect = [self.tableView convertRect:tableViewRowRect
    toView:scrollView];
Run Code Online (Sandbox Code Playgroud)

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

NSView *rootView = self.tableView.window.contentView;
CGRect rootViewRowRect = [self.tableView convertRect:tableViewRowRect
    toView:rootView];
Run Code Online (Sandbox Code Playgroud)

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

CGRect windowRowRect = [self.tableView convertRect:tableViewRowRect
    toView:nil];
Run Code Online (Sandbox Code Playgroud)

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

NSWindow *window = self.tableView.window;
CGRect screenRowRect = [window convertRectToScreen:windowRowRect];
Run Code Online (Sandbox Code Playgroud)