所以我试图在整个屏幕上显示一个窗口覆盖(甚至是停靠栏和菜单栏)捕获所有输入事件,并在Timer定义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开发者来说还是一个新手。
答案 0 :(得分:1)
通过在第二种方法中将窗口级别设置为CGShieldingWindowLevel()来解决它。 不确定这是否正确(Apple允许)并且可以使用(文档说不应该)...