基于NSDocument的应用为何偶尔无法打开全部窗口?
解决NSDocument多窗口偶尔只显示一个的问题
我之前做NSDocument多窗口应用时也碰到过类似的随机失效问题,结合你的代码来看,主要有几个可能的原因和对应的解决办法:
1. 修正Storyboard SceneIdentifier的写法
你的代码里用了NSStoryboard.sceneidentifier(),但Swift中正确的写法是**NSStoryboard.SceneIdentifier()**(注意首字母大写的SceneIdentifier,这是枚举类型的静态成员)。写法错误会导致控制器实例化失败返回nil,自然不会显示对应的窗口。
修正后的实例化代码:
let wc = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("WindowController")) as! NSWindowController wc.contentViewController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(sceneidentifier[x])) as? NSViewController
2. 显式触发窗口显示
虽然addWindowController(_:)理论上会让NSDocument管理窗口显示,但快速添加多个窗口控制器时,AppKit偶尔会漏掉自动显示逻辑。建议添加后手动调用showWindow(_:)确保窗口弹出:
self.addWindowController(wc) wc.showWindow(self) // 显式要求窗口显示
3. 添加错误处理排查实例化失败
为了确认是不是某个控制器实例化失败导致窗口缺失,可以加上guard语句捕获错误,方便调试:
override func makeWindowControllers() { let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil) let sceneIdentifiers : [String] = [ "si1", "si2" ] for x in 0..<sceneIdentifiers.count { // 确保WindowController实例化成功 guard let wc = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("WindowController")) as? NSWindowController else { print("❌ 无法实例化WindowController") continue } // 确保内容ViewController实例化成功 guard let contentVC = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(sceneIdentifiers[x])) as? NSViewController else { print("❌ 无法实例化内容控制器:\(sceneIdentifiers[x])") continue } wc.contentViewController = contentVC self.addWindowController(wc) wc.showWindow(self) } }
4. 排除窗口重叠的假象
有时候窗口其实已经创建,但默认位置完全重叠,看起来像是只显示了一个。可以给每个窗口设置偏移位置验证:
if let window = wc.window { // 每个窗口向右下偏移20pt,避免重叠 let offset = CGFloat(x * 20) let newOrigin = CGPoint(x: window.frame.origin.x + offset, y: window.frame.origin.y - offset) window.setFrameOrigin(newOrigin) }
按照上面的步骤调整后,应该就能解决随机只显示一个窗口的问题了。
内容的提问来源于stack exchange,提问作者EmotionalSnow
相关产品推荐
相关产品推荐

