呈现一个模态视图控制器,但不要隐藏导航栏
Posted
技术标签:
【中文标题】呈现一个模态视图控制器,但不要隐藏导航栏【英文标题】:Present a modal view controller, but don't hide the navigation bar 【发布时间】:2017-11-30 03:41:39 【问题描述】:我正在模态地呈现一个带有半透明视图的 viewController。这是一个自定义活动指示器。我希望它覆盖视图,但保持导航栏和标签栏可见且可访问。
文档和几个 SO 答案(例如Presenting a Modal View Controller hides the Navigation Bar)似乎建议将模式呈现到导航控制器上应该可以实现这一点。但是当我这样做时,它会正确显示标签栏,但会覆盖导航栏。
有什么想法吗?以下是相关代码:
let spinnerVC = SpinnerViewController()
spinnerVC.modalPresentationStyle = .overCurrentContext
spinnerVC.modalTransitionStyle = .crossDissolve
self.navigationController?.present(spinnerVC, animated: true, completion: nil)
//self.navigationController is definitely not nil
【问题讨论】:
【参考方案1】:您可以通过将navigationController
添加为rootViewController
来呈现您的viewcontroller
,然后将其呈现在当前的viewController
上,如下所示:
let spinnerVC = SpinnerViewController()
let navVC = UINavigationController(rootViewController:spinnerVC)
navVC.modalPresentationStyle = .overCurrentContext
navVC.modalTransitionStyle = .crossDissolve
self.present(navVC, animated: true, completion: nil)
【讨论】:
显示带有 a 导航栏的微调器视图。但不是底层的。明确地说,我希望底层导航栏是可见的,并带有其标题和按钮,以便用户可以根据需要导航离开。 要显示底层导航栏,您可以添加 spinnerVC 作为子视图控制器,其动画类似于呈现视图控制器【参考方案2】:你可以通过两种方式做到这一点: 第一个:
将此代码放在您的父视图中
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: animated)
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: animated)
第二个: 在警报控制器中添加对调用者的引用,以便像这样隐藏栏:
weak var invokerView : UIViewController?
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
self.invokerView?.navigationController?.setNavigationBarHidden(true, animated: animated)
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
self.invokerView?.navigationController?.setNavigationBarHidden(false, animated: animated)
【讨论】:
【参考方案3】:不要展示它。将其作为子视图控制器添加到导航控制器的顶部视图控制器中,并将其视图作为子视图添加到相同调整框架的视图中。
let spinnerVC = SpinnerViewController()
spinnerVC.view.frame = self.navigationController?.topViewController?.view.bounds
self.navigationController?.topViewController?.addChildViewController(spinnerVC)
self.navigationController?.topViewController?.view.addSubview(spinnerVC.view)
【讨论】:
是的,我考虑过这个。但是这样做,它需要额外的工作来确保它的行为正确(例如,不可滚动,如果时间错误,则不会在其上显示更多的子视图等)。因为这意味着非常灵活,并且可以在整个应用程序的各种视图中呈现,所以这并不理想。希望有一个简单的模型演示。 模态演示涵盖了整个上下文(包括您的 vc 的导航栏)。您可以调整框架大小以降低高度,但由于底层内容不可见,它将在那里显示为黑色,而不是导航栏。 您可以执行上述操作,但通过创建 UIViewController 的扩展来添加一个可以为您执行此操作的函数,以便它可以在您的整个应用程序中重复使用。 通过使用modalPresentationStyle.overCurrentContext,您可以在其下方有一个模态显示内容。 (例如,在我的情况下,模态视图是半透明的,因此显示了底层视图)。我尝试过调整框架,但在导航控制器上以模态方式呈现时它似乎被覆盖了。 而且,是的,我将使用扩展或其他方法对其进行设置以使其可重用。但这并不妨碍它需要大量额外的逻辑才能在呈现时正确运行,例如滚动视图或表格视图,或者随后可能添加另一个子视图的视图,并且最终会出现在“模态”之上, 如果它只是作为子视图添加。以上是关于呈现一个模态视图控制器,但不要隐藏导航栏的主要内容,如果未能解决你的问题,请参考以下文章
如何在保持导航栏存在的同时以模态方式呈现视图控制器。 (对于设置视图控制器)