You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 3 macOS编程打开窗口传参失败,改用Segue实现成功

macOS Swift 3 编程打开窗口并传递变量的正确方式

问题根源

你最初的代码存在两个关键问题:

  1. 单独实例化的NewViewController和NewWindowController是完全独立的对象,窗口控制器自带的视图控制器并不是你赋值inputString的那个实例
  2. 未将配置好参数的视图控制器与窗口控制器关联,导致窗口无法正确加载目标视图,传参自然也失效

正确的编程式实现方案

修改按钮点击事件代码,先实例化窗口控制器,再获取其内部关联的视图控制器进行参数传递,或者手动将自定义视图控制器绑定到窗口控制器:

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:23:36