【问题标题】:How do I open another window in macOS in Swift with Cocoa如何在 macOS 中使用 Cocoa 在 Swift 中打开另一个窗口
【发布时间】:2017-12-20 13:10:54
【问题描述】:

我正在开发一个 macOS 应用程序,该应用程序在表格视图中显示客户主记录列表。双击表格视图中的一行应该会打开一个新窗口,用户可以在其中查看和编辑客户信息。

这是一个使用故事板和 Swift 的 Xcode 8.3.3 项目。
它不是文档或核心数据应用程序。

我的主窗口工作到表视图正确显示记录并且关联的视图控制器正在接收双击事件并将它们记录到控制台。

我为编辑窗口创建了一个额外的窗口控制器和视图,并通过临时将其标记为初始控制器来验证其基本功能。

我无法弄清楚当用户双击一行时如何显示该窗口的新实例。

感谢@Joshua Nozzi,我离我更近了。这是此时的代码。

let storyboard = NSStoryboard(name: "Main", bundle: nil)
if let windowController = storyboard.instantiateController(withIdentifier: "xyzzy") as? NSWindowController
{
  windowController.showWindow(self)
}

它正在生成一个

(Storyboard: 0x620000000680) 不包含带有 标识符“xyzzy”

错误。

【问题讨论】:

    标签: swift macos cocoa xcode8


    【解决方案1】:

    Window Programming Guide 是了解一般窗口管理方式的好地方。

    具体来说(假设您知道如何在情节提要中呈现窗口控制器场景),您需要在某个地方存储对新窗口控制器的引用,这样它们在呈现时不会立即被释放(并消失)。

    在您的情况下,您可能希望在主窗口控制器中保留一组打开的详细信息窗口,这样如果主窗口控制器消失了,详细信息也会这样做。当一个详细信息窗口打开时(创建一个控制器实例并显示它的窗口),您将把它的控制器存储在数组中;当关闭时,你从数组中移除它的控制器,这样它就被释放了。

    有很多方法可以做到这一点,具体取决于您想要多少控制,您希望子窗口所有权如何工作等,但这种基本模式通常就足够了。

    从情节提要中实例化一个新的窗口控制器场景:

    var myWindowController = NSStoryboard(name: "MyStoryboardFileName", bundle: nil)?.instantiateControllerWithIdentifier("MyWindowControllerIdentifier") as MyWindowControllerClass
    myWindowController?.showWindow(self)
    

    【讨论】:

    • 我还没有完整地阅读 Window Programming 指南,但今天早上我确实花了大约一个小时在里面,但没有找到如何实际实例化新控制器的示例和显示窗口和视图。我创建项目时创建的任何 Xcode 都会自动显示当前窗口。另外,我是 Swift 和 Cocoa 的新手,但总的来说我是一位非常有经验的开发人员。
    • 啊。在这种情况下,请参阅我的答案的补充。 :-)
    • 酷。几小时前我就走在了正确的轨道上。现在的问题是窗口控制器标识符从何而来?
    • 您确定为 window controller 而不是 window 设置 storyboard 标识符吗? It's actually the third tab and when the controller is selected, it's under Identity, called "Storyboard ID".当然,它是区分大小写的。
    • 就是这样。结果是单击情节提要中的窗口控制器窗口会选择控制器内的窗口。您必须单击窗口控制器“标题栏”(控制器和第一响应者图标所在的位置),而不是。非常感谢您的帮助。
    【解决方案2】:

    另外,要打开新窗口,这段代码可以帮助你

    windowController.contentViewController = tabViewController

    完整的代码就像我在我的项目中使用的那样:

    @objc func openApplicationView(_ sender: Any?) {
        let mainStoryBoard = NSStoryboard(name: "Main", bundle: nil)
        let tabViewController = mainStoryBoard.instantiateController(withIdentifier: "tabView") as? TabViewController
        let windowController = mainStoryBoard.instantiateController(withIdentifier: "secondWindow") as! TabViewWindowController
        windowController.showWindow(self)
        windowController.contentViewController = tabViewController
    }
    

    关闭 ma​​inWindow 会很有帮助。所以你需要在自己的底层storyboard中添加一个windowControllertabViewController(可以使用普通视图控制器)。

    在我这边,tabViewController 已被 NSTabViewController 扩展,并且标签视图组件已与此类绑定。

    注意:我还在 Main.storyboard 中添加了 windowController 作为组件,并确定在编码端使用。

    【讨论】:

      【解决方案3】:

      已确认。这是 UI 中的一个重大问题。而且开机很麻烦: Storyboard doesn't contain a controller with identifier 'MainWindow' 解决这个问题浪费了一整天。

      【讨论】:

      • 请在此处复制答案,而不是链接。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      相关资源
      最近更新 更多