在10.14无Storyboard的Swift菜单栏应用中,如何复用窗口而非创建重复窗口?
解决macOS菜单栏应用窗口复用问题
问题核心在于:默认情况下NSWindow关闭时会被销毁(isReleasedWhenClosed默认值为true),导致你保存的NSWindowController实例的window属性变为nil,无法再次显示。
解决方案步骤:
- 在处理菜单命令的类(比如
AppDelegate或自定义菜单管理类)中,将窗口控制器作为类属性保存,避免每次创建新实例:
private var changelogWindowController: NSWindowController?
- 修改菜单点击的处理方法,复用已有的窗口控制器,并调整窗口的关闭行为:
@objc func showChangelogWindow() { if let existingController = changelogWindowController { // 复用已存在的窗口控制器,直接显示窗口 existingController.window?.makeKeyAndOrderFront(nil) } else { // 首次创建窗口控制器 let controller = NSWindowController(windowNibName: "Changelog") controller.loadWindow() // 关键设置:关闭窗口时不销毁窗口对象,仅隐藏 controller.window?.isReleasedWhenClosed = false controller.window?.makeKeyAndOrderFront(nil) // 保存实例供后续复用 changelogWindowController = controller } // 激活应用,确保窗口显示在最前端 NSApp.activate(ignoringOtherApps: true) }
原理说明:
- 将
isReleasedWhenClosed设为false后,用户关闭窗口时系统只会隐藏窗口,不会销毁NSWindow对象,因此后续可以通过窗口控制器重新调用makeKeyAndOrderFront显示窗口。 - 类属性保存的
NSWindowController实例会一直持有窗口对象,避免被ARC自动释放。
内容的提问来源于stack exchange,提问作者CXL
相关产品推荐
相关产品推荐

