将一个透明的NSWindow永久置于另一个NSWindow之上

8
我希望在NSWebView的顶部添加一些UI控件,因为存在这个问题“https://stackoverflow.com/questions/9120868/video-in-nswebview-hides-views-on-top-of-the-nswebview”,所以现在我想在NSWebView的顶部添加一个“透明”的NSWindow,没有关闭按钮等,因此在我的当前NSWindow的顶部。

我该如何实现,并确保这个“覆盖窗口”保持在原位,即使我移动底层窗口?

编辑::虽然@dzolanta的方法很好用,但我想知道是否可以使用NSWindowController来完成,这将允许我正确地使用Outlets等。

2个回答

21

您需要的是子窗口。

使用NSBorderlessWindowMask创建NSWindow,并使用-setOpaque:-setBackgroundColor:方法将其定义为透明。然后将新创建的窗口作为包含NSWebView实例的窗口的子窗口添加(使用NSWindow-addChildWindow:ordered:方法)。移动父窗口将自动导致子窗口移动。

附带可工作代码更新:

CGRect wRect = self.window.frame;
NSView *contentView  =self.window.contentView;
CGRect cRect = contentView.frame;

CGRect rect = CGRectMake(wRect.origin.x, wRect.origin.y, cRect.size.width, cRect.size.height);
NSWindow *overlayWindow = [[NSWindow alloc]initWithContentRect:rect 
                                                     styleMask:NSBorderlessWindowMask 
                                                       backing:NSBackingStoreBuffered 
                                                         defer:NO];
overlayWindow.backgroundColor = [NSColor redColor];
[overlayWindow setOpaque:NO];
overlayWindow.alphaValue = 0.5f;

[self.window addChildWindow:overlayWindow ordered:NSWindowAbove];

我已成功显示窗口,并且它也在我的视频流顶部。唯一还没有实现的是当包含窗口被调整大小时,该窗口应该随之拉伸。 - Besi
4
为了实现这一点,注册您的窗口控制器(或另一个对象,取决于您的应用程序架构)作为NSWindowDidResizeNotification的观察者。通知选择器应指定一种方法,该方法根据父窗口的框架更改子窗口的框架(就像创建覆盖窗口时一样)。如果您喜欢,也可以使用NSWindowDelegate的-windowDidResize:方法。 - dzolanta

0

Swift 3 版本使用窗口控制器:

final class OverlayWindowController: NSWindowController {
  init(frame: NSRect) {
    let window = NSWindow(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false)
    super.init(window: window)

    window.contentViewController = MyViewController()
    window.backgroundColor = NSColor.clear
    window.isOpaque = false
  }

  @available(*, unavailable)
  required init?(coder: NSCoder) {
    fatalError("init(coder:) is unavailable")
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接