Swift 5:代码创建的NSWindow无法悬浮在全屏应用上方怎么办?
解决代码创建NSWindow无法悬浮在全屏应用上方的问题
我来帮你搞定这个问题~你遇到的核心问题是代码创建窗口时,collectionBehavior的设置时机不对,导致它没有被系统正确应用。下面是修正后的实现方案,以及原因分析:
修正后的代码实现
WindowController 类
class WindowController: NSWindowController { init() { // 初始化窗口时先给一个基础的contentRect,全屏后会自动覆盖整个屏幕 let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 800, height: 600), styleMask: [], backing: .buffered, defer: false) super.init(window: window) } override func windowDidLoad() { super.windowDidLoad() guard let window = self.window else { return } // 按顺序设置属性:先配置行为,再设置全屏样式 window.backgroundColor = .red window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.mainMenuWindow))) // 先设置collectionBehavior,确保系统后续处理不会覆盖 window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary] // 设置全屏样式 window.styleMask = [.fullScreen] // 主动触发全屏流程,确保配置生效 window.toggleFullScreen(nil) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } }
AppDelegate 类
@NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { var windowController: WindowController! func applicationDidFinishLaunching(_ aNotification: Notification) { windowController = WindowController() windowController.showWindow(self) } }
问题原因分析
你原来的代码有两个关键问题:
- 属性设置时机过早:在
init方法中直接设置窗口属性时,窗口还没有完成完整的初始化流程。当你设置styleMask = .fullScreen时,系统会触发默认的全屏处理逻辑,这可能会重置你之前设置的collectionBehavior。而windowDidLoad是窗口完全加载完成后的回调,在这里设置属性能确保系统不会覆盖你的配置。 - 全屏触发方式不够可靠:直接设置
styleMask为.fullScreen只是修改了窗口样式,但没有触发系统完整的全屏生命周期流程。调用toggleFullScreen(nil)会让系统按照标准流程处理全屏,确保collectionBehavior的配置被正确识别。
这样修改后,你的代码创建的窗口应该就能像Storyboard方式一样,稳定悬浮在全屏应用上方了~
内容的提问来源于stack exchange,提问作者Hish
相关产品推荐
相关产品推荐

