如何在同一个Mac窗口中显示新的视图控制器?

时间:2015-01-25 17:30:51

标签: macos cocoa swift

我对Mac开发相当新,并且对Xcode 6中的新“故事板”功能感到有些困惑。我想要做的是在同一个窗口中从一个视图控制器切换到另一个视图控制器。截至目前,所有不同的NSViewControllerSegues在一个新窗口中呈现视图控制器,无论是模态还是仅仅是另一个窗口。我想做的只是在同一个窗口中进行segue,就像在iOS上一样(尽管动画过渡并不重要)。如何实现这一目标?

3 个答案:

答案 0 :(得分:32)

如果您提供自定义segue(NSStoryboardSegue的子类),您可以获得您所追求的结果。但是这种方法有一些 gotchas

  • 自定义segue将使用presentViewController:animator,因此您需要提供动画对象
  • 因为所呈现的视图不是由单独的Window对象支持,您可能需要为其提供自定义NSView,以便捕获您不希望传播到底层NSViewController的鼠标事件。图
  • 还有一个关于自定义segue identifier属性的Swift-only故障,需要注意。

由于似乎没有关于此的大量文档,我在Swift和Objective-C中使用自定义segue示例创建了small demo project

enter image description here

我还在回答this question时提供了更多细节。

答案 1 :(得分:7)

(恢复这一点,因为它出现在谷歌的第一个相关结果,我有同样的问题,但决定反对自定义segue)

虽然自定义segues工作(至少,代工厂的答案中提供的代码在Swift 3下运行;它需要更新Swift 4),编写自定义动画师所涉及的大量工作向我建议他们的主要用例是自定义动画。

更改窗口内容的简单解决方案是为窗口创建NSWindowController,并将其contentViewController设置为所需的viewController。如果您遵循故事板的典型模式并在每次切换时实例化一个新的ViewController实例,这将特别有用。

然而

NSStoryboard documentation非常清楚在macOS中,包含(而不是转换)是故事板的更常见的概念,这使我再次查看可用的工具。

您可以使用容器视图执行此任务,该视图会添加NWViewController图层,而不是上面概述的NSWindowController。我使用的解决方案是使用NSTabViewController。在属性检查器中,将样式设置为“未指定”TabViewController settings,然后选择TabView并将样式设置为“tabless”。 TabView selection TabView Settings

要以编程方式更改标签,请设置TabViewController的selectedTabViewItemIndex

此解决方案为选项卡内容重用ViewControllers的相同实例,以便在用户切换到另一个“选项卡”时保留在文本字段中输入的任何数据。

答案 2 :(得分:2)

一种简单的方法,无需在同一个窗口中替换当前视图控制器:

if let myViewController = self.storyboard?.instantiateController(withIdentifier: "MyViewController") as? MyViewController {
    self.view.window?.contentViewController = myViewController
}