10

我有一个 NSScrollView 填充整个窗口并显示一个巨大的图像。现在我想在部分滚动视图(例如前 20 个像素高度和窗口宽度)上覆盖一个自定义 NSView 以显示其他信息。当用户滚动滚动视图时,顶部的自定义 NSView 应该保持在原来的位置。

我尝试了以下方法:

  1. 创建我的窗口大小的 NSView 实例
  2. 添加 NSScrollView 作为之前生成的 NSView 的子视图
  3. 在步骤 1 中将我的自定义视图作为子视图添加到 NSView

这在开始时有效,滚动视图正确显示,我的自定义 NSView 也是如此。但是,一旦我开始移动滚动视图(滚动),自定义 NSView 就会与 NSScrollView 的内容一起滚动,并最终在其移动到边界之外时消失,并且它所在的滚动视图部分会重新绘制. 我怎样才能有效地将我的自定义 NSView 放在 NSScrollView 之上并确保它保持不变?

谢谢!

4

2 回答 2

9

你有两个选择:

首先,关闭“滚动复制”。您可以直接在 IB 中执行此操作,也可以通过copiesOnScroll在. 该选项默认启用,因此滚动视图“在滚动时复制其现有的渲染图像(仅绘制其文档视图的暴露部分)”。如果关闭,“它会强制每次重绘其内容”。因此,如果性能不是一个大问题,只需将其关闭即可。contentViewNSScrollView

但是,如果您在滚动视图中进行复杂的绘图,那么每次都必须重绘内容可能会导致严重的性能问题。

第二个选项是打开“滚动复制”,然后创建一个包含覆盖视图的无边框窗口。这实际上并不像听起来那么骇人听闻,因为您实际上可以添加一个NSWindow实例作为当前窗口的子窗口,以便在移动时它会自动与主窗口一起移动。

RoundTransparentWindow示例将为您提供一个很好的示例来创建包含您的覆盖的窗口。然后,只需使用 NSWindowaddChildWindow将其附加到您的主窗口。

请注意,使用这种方法,您将需要处理覆盖窗口的呈现和隐藏​​时间。当您最大化父窗口时,子窗口位置似乎也不会自动调整。所以,你也必须处理它。但是,如果您不想牺牲使用“滚动复制”时有时会带来巨大的性能改进,那么这是一个很好的解决方案。

于 2011-01-21T22:13:46.110 回答
3

我知道你已经有了一个可行的解决方案,但我最近碰巧自己也在寻找同样的东西,我遇到了Louis Klaassen 的LKOverlayWindow类,它似乎为这种覆盖提供了一个简单的解决方案。

CocoaDev wiki中所述,您只需要在 Interface Builder 中创建一个新的 NSWindow,让它成为 LKOverlayWindow 的一个实例,然后通过插座附加 NSScrollView 或在代码中指定它。一旦附加到滚动视图,LKOverlayWindow 的内容将覆盖滚动视图并在它移动和调整大小时跟踪它(后者似乎只与 NSScrollView 作为窗口的出口一起使用)。作者在此处提供了一个示例项目。

我打算采用继承 NSScrollView 的方式,但在我的情况下,这要容易得多。

于 2011-02-15T04:30:27.793 回答