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

How does one display a new view controller in the same Mac window?

我是 Mac 开发的新手,对 Xcode 中的新 "storyboard" 功能感到有点困惑 6. 我想做的是从一个视图中继续控制器到同一 window 中的另一个。截至目前,所有不同的 NSViewControllerSegues 都以新的 window 形式呈现视图控制器,无论是模态模式还是另一个 window。我想做的只是在同一个 window 中继续,与在 iOS 上的方式大致相同(尽管动画过渡并不重要)。这将如何实现?

如果您提供自定义转场(NSStoryboardSegue 的子类),您可以获得您想要的结果。不过,这种方法有一些 陷阱

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

由于似乎没有太多关于此的文档,我在 Swift 和 Objective-C.

中制作了一个带有自定义 segue 示例的 small demo project

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

(在 Google 上作为第一个相关结果出现时恢复它,我遇到了同样的问题但决定不使用自定义 segue)

虽然自定义 segues 工作(至少,铸造厂的答案中给出的代码在 Swift 3 下工作;它需要更新 Swift 4),但编写自定义的工作量巨大动画师向我建议他们的主要用例是自定义动画。

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

但是

NSStoryboard documentation 说得很清楚 在 macOS 中,包含(而不是过渡)是故事板的更常见概念,这让我再次查看可用的工具。

您可以为此任务使用容器视图,它添加一个 NWViewController 层而不是上面概述的 NSWindowController。我采用的解决方案是使用 NSTabViewController。在属性检查器中,将样式设置为 'unspecified', then select the TabView and set its style to 'tabless'.

要以编程方式更改选项卡,请设置选项卡的 selectedTabViewItemIndexViewController。

此解决方案为选项卡内容重复使用 ViewController 的相同实例,因此当用户切换到另一个 'tab' 时,在文本字段中输入的任何数据都会被保留。

在同一个 window:

中不涉及替换当前视图控制器的简单方法
if let myViewController = self.storyboard?.instantiateController(withIdentifier: "MyViewController") as? MyViewController {
    self.view.window?.contentViewController = myViewController
}