【发布时间】:2018-03-05 02:24:38
【问题描述】:
所以我试图在整个屏幕(甚至停靠栏和菜单栏)上显示一个窗口覆盖,捕获所有输入事件,并在定时器定义 x 秒后隐藏它。我知道这是可能的,因为 AppStore 中有一个应用程序可以做到这一点。
我找到了两种方法: 第一:
let windowLevel = CGShieldingWindowLevel();
let windowRect = NSScreen.main?.frame
var overlayWindow = NSWindow(contentRect: windowRect!, styleMask: NSWindow.StyleMask.borderless, backing: NSWindow.BackingStoreType.buffered, defer: false, screen: NSScreen.screens[0])
overlayWindow.level = NSWindow.Level(rawValue: NSWindow.Level.RawValue(windowLevel))
overlayWindow.backgroundColor = .black
overlayWindow.alphaValue = 0.4
overlayWindow.makeKeyAndOrderFront(nil)
overlayWindow.makeMain()
第二: 使用故事板
let window = FullScreenWindowController(windowNibName: NSNib.Name(rawValue: "FullScreenWindow"))
self.application.runModal(for: self.window.window!)
第一种解决方案导致出现此日志:
Assertion failure in -[NSWindow _changeJustMain], /Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1504.83.101/AppKit.subproj/NSWindow.m:14861
Invalid parameter not satisfying: [self canBecomeMainWindow]
而且在显示模式时我也无法运行计时器。模态阻止所有事件并且计时器循环不能发生。 我看到了一些使用 NSRunner looper 的方法......但我不确定这在当前的 SDK 版本中是否仍然可行。
至于第二种解决方案,我无法恢复初始应用状态,我的意思是在显示后隐藏覆盖。 此解决方案的另一个缺点是 Dock 仍然可见并且可以进行交互。
不胜感激,因为我对 MacOS 开发人员还很陌生。
【问题讨论】: