Swift 3 macOS编程打开窗口传参失败,改用Segue实现成功
macOS Swift 3 编程打开窗口并传递变量的正确方式
问题根源
你最初的代码存在两个关键问题:
- 单独实例化的
NewViewController和NewWindowController是完全独立的对象,窗口控制器自带的视图控制器并不是你赋值inputString的那个实例 - 未将配置好参数的视图控制器与窗口控制器关联,导致窗口无法正确加载目标视图,传参自然也失效
正确的编程式实现方案
修改按钮点击事件代码,先实例化窗口控制器,再获取其内部关联的视图控制器进行参数传递,或者手动将自定义视图控制器绑定到窗口控制器:
方案1:复用窗口控制器自带的视图控制器
@IBAction func ButtonClicked(_ sender: Any) { let storyboard = NSStoryboard(name: "Main", bundle: nil) // 先实例化窗口控制器 let newWindowController = storyboard.instantiateController(withIdentifier: "NewWindowController") as! NSWindowController // 获取窗口控制器关联的视图控制器并传参 if let newVC = newWindowController.contentViewController as? NewViewController { newVC.inputString = outputString } // 显示窗口 newWindowController.showWindow(self) }
方案2:手动绑定自定义视图控制器
如果你的窗口控制器在Storyboard中没有预设关联的视图控制器,可使用此方式:
@IBAction func ButtonClicked(_ sender: Any) { let storyboard = NSStoryboard(name: "Main", bundle: nil) let newVC = storyboard.instantiateController(withIdentifier: "NewViewController") as! NewViewController let newWindowController = storyboard.instantiateController(withIdentifier: "NewWindowController") as! NSWindowController newVC.inputString = outputString newWindowController.contentViewController = newVC newWindowController.showWindow(self) }
Segue方式的补充说明
你通过Interface Builder创建Segue并在prepare(for:sender:)中传参的方式完全可行,这种方式更简洁,适合无需复杂逻辑触发窗口打开的场景:
override func prepare(for segue: NSStoryboardSegue, sender: Any?) { if segue.identifier == "TestSegue" { let newVC = segue.destinationController as! NewViewController newVC.name = "test" } }
这种方式下,Storyboard会自动处理控制器之间的关联和窗口显示逻辑,无需手动管理实例关系。
内容的提问来源于stack exchange,提问作者Bob7430
相关产品推荐
相关产品推荐

