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

Posted

技术标签:

【中文标题】如何在同一个 Mac 窗口中显示新的视图控制器?【英文标题】:How does one display a new view controller in the same Mac window? 【发布时间】:2015-01-25 17:30:50 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

由于似乎没有太多关于此的文档,我制作了一个small demo project,其中包含 Swift 和 Objective-C 中的自定义 segue 示例。

我在回复this question 时也提供了一些更详细的信息。

【讨论】:

您在 GitHub 上提供的示例项目非常有用!尝试从 iOS 开发调整到 macOS 开发对我来说并不容易,所以非常感谢代码。一个问题,如何在 macOS 上制作推送视图控制器动画? (如 macOS Tweetbot 应用程序)。 此解决方案的主要问题是当您尝试调整窗口大小时,呈现的视图控制器不会像父视图控制器那样调整大小。然而,它有助于理解 segue 与 iOS segues 相比是如何工作的。我建议使用下面的@green_knight 解决方案,它既轻松又非常优雅【参考方案2】:

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

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

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

但是。

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

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

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

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于如何在同一个 Mac 窗口中显示新的视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

导航控制器不推送新窗口

如何设置新的根视图控制器

如何设置Eclipse界面!

在Mac应用中使用SwiftUI更改动画窗口大小

通过 UIScrollView 推送 ViewController

应用程序中多个 UIWindow 的最佳实践