在NSScrollView上覆盖NSView

时间:2011-01-18 10:50:42

标签: cocoa overlay nsview nsscrollview

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

我尝试了以下内容:

  1. 创建一个与我的窗口大小相同的NSView实例
  2. 将NSScrollView添加为先前生成的NSView
  3. 的子视图
  4. 将我的自定义视图作为子视图添加到步骤1中的NSView
  5. 这在开始时工作,滚动视图正确显示,我的自定义NSView也是如此。但是,一旦我开始移动滚动视图(滚动),自定义NSView就会随着NSScrollView的内容一起滚动,并且当它移动到边界之外时最终会消失,并且滚动视图的位置(它被定位的位置)会重新绘制。我怎样才能在NSScrollView上有效地将我的自定义NSView分层并确保它保持不变?

    谢谢!

2 个答案:

答案 0 :(得分:9)

您有两种选择:

首先,关闭“滚动时复制”。您可以直接在IB中执行此操作,也可以在copiesOnScroll的{​​{1}}成员上设置contentView选项。该选项默认启用,因此滚动视图“在滚动时复制其现有的渲染图像(仅绘制其文档视图的外露部分)”。如果关闭,“它会强制每次重绘其内容。”因此,如果性能不是一个大问题,那么它可以解决这个问题。

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

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

RoundTransparentWindow示例将为您提供一个很好的示例,可以创建包含叠加层的窗口。然后,只需使用NSWindow的NSWindow将其附加到主窗口。

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

答案 1 :(得分:3)

我知道你已经有了一个可行的解决方案,但我最近自己正在寻找相同的东西,而且我遇到了Louis Klaassen的LKOverlayWindow课程,这似乎为我提供了一个简单的解决方案。这种叠加。

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

我打算继承NSScrollView的子类,但在我的情况下,这变得更容易。