UINavigationController 作为 MSMessagesAppViewController 的子视图

UINavigationController as subview to MSMessagesAppViewController

我正在创建一个 iMessage 扩展程序,其中 扩展的演示文稿样式 我想使用 UINavigationController。我正在尝试使用以下函数将导航控制器添加为 MSMessagesAppViewController 的子视图:

private func present(viewController: UIViewController) {
    viewController.view.frame = view.frame

    addChildViewController(viewController)
    viewController.didMove(toParentViewController: self)

    view.addSubview(viewController.view)
}

我原以为导航控制器会以传统方式显示,其导航栏从 iMessage 本身的顶部栏下方开始。我的预期结果请看下图:

但是,似乎 view.frame 实际上延伸到 iMessage 顶部栏下方。因此,我的导航控制器的导航栏隐藏在 iMessage 的顶部栏下方。然而,滚动视图本身的内容视图无需进一步定制即可正确定位。实际效果请看下图:

显然,我可以将导航控制器的框架设置为刚好在顶栏下方开始。但是,我正在寻找不太依赖硬编码位置的解决方案。如果这样做,滚动视图也不会在 iMessage 顶部栏下方继续以达到半透明效果。

理想情况下,导航栏将显示在 iMessage 顶部栏的正下方,就像默认情况下的滚动视图一样。

有谁知道解决这个问题的方法吗?

经过一番深思熟虑,我找到了一个非常棘手的解决方案。我仍在接受反馈和其他答案。

可以通过创建一个初步的 layoutView 来实现上述目标,它被限制在使用 AutoLayout 的布局指南中。然后,通过设置 UINavigationController 的框架来匹配布局视图的框架,它实际上只会占据可见区域。

您可以使用 Storyboard 设置像我这样的视图,如下所示:

然后在您的容器视图控制器中(createStickerViewController 在我的例子中)只要满足约束就将您的 UINavigationController 的框架分配给布局视图的框架:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Update frame after constraints have been satisfied for layoutView
    pickAssetNavigationController.view.frame = layoutView.frame
}

结果是导航控制器只占据实际可见区域,因此导航栏按预期放置在 iMessage 顶部栏的正下方(参考原问题中的图 1)。