【问题标题】:Present View Controller Over current tabBarController with NavigationController使用 NavigationController 显示当前视图控制器
【发布时间】:2026-01-06 05:00:02
【问题描述】:

在展示或关闭 VC 时,我不想一直隐藏和显示 tabBar,因为它会造成糟糕的用户体验。相反,我想直接在标签栏上显示下一个 VC,这样当我通过从左到右缓慢拖动来关闭下一个 VC 时,我可以看到隐藏在视图后面的 tabBar(如下图所示)

注意,我的应用有两个选项卡,其中有两个 VC(VCA,VCB)与之关联。两个 VC 还嵌入了导航栏。 VCA 连接到 VCA1,VCB 连接到 VCB1。目前,在 VCA 和 VCB 内部,我正在调用以下函数,以便在 viewWillappear 时完成一些隐藏和取消隐藏(代码如下)。

self.navigationController?.showViewController(vc, sender: self)

  // Inside ViewWillAppear Only reappear the tab bar if we successfully enter Discover VC (To prevent drag back half way causing tab bar to cause comment entry to be floating). This code check if we have successfully enters DiscoverVC
    if let tc = transitionCoordinator() {
        if tc.initiallyInteractive() == true {
            tc.notifyWhenInteractionEndsUsingBlock({(context: UIViewControllerTransitionCoordinatorContext) -> Void in
                if context.isCancelled() {
                    // do nothing!
                }
                else {
                    // not cancelled, do it
                    self.tabbarController.tabBar.hidden = false
                }
            })
        } else {
            // not interactive, do it
            self.tabbarController.tabBar.hidden = false
        }
    } else {
        // not interactive, do it
        self.tabbarController.tabBar.hidden = false
    }

---------来自GOKUL的工作解决方案-----------

Gokul 的答案几乎是准确的。我已经使用了他的解决方案,并提出了以下改进,以消除对冗余 VC 的需要,并消除了在 tabVC 出现之前显示初始 VC 的短暂时间。但是如果没有 Gokul,我永远不会想出这个!

此外,Gokul 的方法会为我创建一个错误,因为即使在显示 tabVC 之前我确实有一个作为 LoginVC 的初始“正常”VC。如果用户需要登录,这个 loginVC 只是 rootVC。因此,在大多数情况下,通过将 rootVC 设置为 tabVC,navVC 将永远不会被注册。

解决方案是将导航控制器和tabBar控制器嵌入到一个VC中。但它仅适用于 navVC 在 TabBarVC 之前。我不知道为什么,但让我拥有 navVC-> tabVC-> VC1/VC2 的唯一方法是先用 navVC 嵌入 VC1,然后再次单击 VC1 以嵌入 tabVC(它不允许我之前插入一个tabVC 和我还必须在嵌入 NavVC 后再次单击 VC1)。

【问题讨论】:

    标签: ios swift uiviewcontroller


    【解决方案1】:

    第一种方法是使用UIGraphicsGetImageFromCurrentImageContext 创建标签栏的图像并将其设置在另一个视图的底部...

    第二种方法是在标签栏上方的另一个新窗口中显示下一个视图,这样您就不需要再隐藏标签栏了,但它似乎在导航控制器中,所以这种方式似乎不可用

    【讨论】:

      【解决方案2】:

      隐藏和取消隐藏标签栏是不必要的。您只需将UITabBarController 嵌入到UINavigationController 中。即UINavigationController为初始vc,UITabBarControllerUINavigationController的根vc。

      【讨论】:

        【解决方案3】:

        根据您的要求,我们需要在您给定的视图层次结构中进行一些小的更改

        • 让我一步一步解释,

          1. 为了满足您的要求,我们必须添加一个嵌入了UINavigationControllerUIViewController(比如说InitialVC),并将其设为initial viewcontroller

            李>
          2. 然后添加带有 2 个 VC (VCA,VCB) 的 UITabbarController // 重要提示: 没有嵌入任何 navigationcontroller

          3. InitalVCTabbarController 之间添加一个 segue,并带有唯一标识符(例如:Initial)

          4. InitalVCviewWillAppear 中执行如下的 segue(InitialVC 对我们的设计来说是不必要的,我们使用它只是为了连接 navigationControllertabbarController)。

                self.performSegueWithIdentifier("Initial", sender: nil)
            
          5. TabbarControllerclass 中隐藏你的后退按钮,这样可以确保InitialVC 无法访问。

                override func viewDidLoad() {
                   super.viewDidLoad()
                   self.navigationItem.hidesBackButton = true
                }
            
          6. 现在从 VCAVCA1 之间的按钮添加一个 segue,这样就可以构建并运行,您将看到 VCA1 出现在 VCA 的标签栏上。

        • 我们改变了什么?

          1. 我们没有在UITabbarController 中添加UINavigationController,反之亦然。我们不能直接在导航中添加 Tabbar 来做到这一点,因为我们在它们之间使用了 InitialVC

        结果:

        【讨论】:

        • 很好的解释和很好的解决方案!非常感谢。我已经为任何需要它的人更新了我的答案,并在上面进行了一些改进
        最近更新 更多