Mac Dock下主窗口关闭后,如何实现窗口重新显示?
窗口关闭后重新显示问题的解决方法
问题描述
已处理窗口最小化和不可见的显示逻辑,但窗口关闭后无法重新显示,尝试新建窗口时程序崩溃,相关代码如下:
@objc func showMainWindow() { DispatchQueue.main.async { NSApp.activate(ignoringOtherApps: true) var windowsCount = 0 for windows in NSApp.windows { if windows.isMiniaturized { windows.deminiaturize(self) } if !windows.isVisible { windows.makeKeyAndOrderFront(self) } windowsCount+=1 } print(windowsCount) if(windowsCount <= 2){ print("window closed") } } }
问题根源
窗口关闭后默认会被ARC释放,NSApp.windows列表中不再存在该窗口实例;新建窗口时崩溃通常是因为没有正确持有窗口/窗口控制器的引用,导致实例被立即释放。
解决方案
方案1:修改窗口关闭行为(推荐)
让窗口关闭时仅隐藏而非销毁,这样后续可以直接重新显示:
- 在窗口控制器中重写
windowShouldClose(_:)方法:override func windowShouldClose(_ sender: NSWindow) -> Bool { sender.orderOut(nil) // 隐藏窗口 return false // 阻止窗口销毁 } - 或者在窗口初始化时设置属性:
这样窗口关闭后仍保留在window?.isReleasedWhenClosed = falseNSApp.windows中,你的原有逻辑可以直接将其重新显示。
方案2:正确重建窗口(需销毁窗口时使用)
如果必须销毁窗口,重建时要确保持有窗口控制器的引用:
- 在类中声明属性保存窗口控制器:
var mainWindowController: NSWindowController? - 修改
showMainWindow中的新建窗口逻辑:if windowsCount <= 2 { // 从Storyboard加载主窗口控制器(替换为你的Storyboard名称和控制器标识符) let storyboard = NSStoryboard(name: "Main", bundle: nil) guard let windowController = storyboard.instantiateController(withIdentifier: "MainWindowController") as? NSWindowController else { print("加载主窗口控制器失败") return } windowController.window?.makeKeyAndOrderFront(self) mainWindowController = windowController // 持有引用,避免被释放 }
方案3:优化现有显示逻辑
过滤掉系统窗口,只处理你的主窗口,避免误操作:
for window in NSApp.windows { // 匹配主窗口(可通过标题、标记或是否为主窗口判断) if window.isMainWindow { if window.isMiniaturized { window.deminiaturize(self) } if !window.isVisible { window.makeKeyAndOrderFront(self) } } windowsCount += 1 }
内容的提问来源于stack exchange,提问作者Kevin Dev
相关产品推荐
相关产品推荐

