你能在 UINavigationController 中嵌套一个 UITabBarController 吗?

4

在UINavigationController中推入UITabBarController是否可行?我曾经在旧版本的iOS中阅读过相关内容,但现在是否仍然如此?


2
好吧,苹果不希望你这样做,但我花了大约90秒来测试并发现你可以这样做。你是否应该这样做是更重要的问题——因为苹果说你不应该这样做,我不知道他们是否会批准这样的设计,或者你是否会从这样的设计中遇到意外后果。 - rdelmar
我在尝试从导航控制器中的初始视图推出uitabbarcontroller时遇到了很多麻烦。推出后,uitabbarcontroller只是白屏。你是否在选项卡中放置了导航控制器并拥有可用的uitabbarcontroller? - Mike Flynn
5个回答

5
简单来说,是的,你可以使用UITabBarController。但仅仅因为你可以使用它,并不意味着你应该这么做。UITabBarController被设计成在根级别作为viewController(app窗口的rootViewController)使用,旨在为用户提供最佳(且易用)的用户体验。苹果建议保持应用程序的视图层次结构,使得从一个视图控制器到另一个视图控制器只有一条路径。
广泛接受的使用UITabBarController的方式是将其设置为rootViewController,并为每个“选项卡”分配UIViewControllers。如果您想要能够从这些视图控制器推入/弹出,则可以为每个选项卡分配一个UINavigationController,并且它们具有自己的rootViewController,就像Facebook iOS应用程序一样。
如果您决定将其推入UINavigationController中,则建议在每个选项卡中使用简单的viewControllers,而不是UINavigationController,以避免多个视图层次结构。其余的则由您作为开发人员自行决定。在任何情况下,编码容易性都不应影响最终用户的体验,用户体验始终是最重要的。
编辑:
  1. Create a UITabBarController.

  2. You set the root view controllers for each tab using:

    tabBarController.viewControllers = [NSArray arrayWithObjects:
                                             alphaController,
                                             betaController,
                                             nil];
    
  3. Push it onto your navigation controller.

  4. In the viewDidLoad method of your UITabBarController class (advised to subclass), you set it's UITabBar's items (UIBarButtonItems).

通过使用UITabBarControllerDelegate,您可以处理选项卡的选择。您不一定需要在选项卡选择时显示viewControllers。您可以通过覆盖shouldSelectViewController:方法来改变它们的行为。


非常抱歉,我无法添加来自苹果文档的参考资料。由于某种原因,开发者门户网站在我的端口上无法访问。一旦我能够访问,我会立即添加适当的参考资料。 - n00bProgrammer

1
你可以这样做,但是由于文档中说不应该这样做,这可能会导致问题。我之前在导航栈中放置了一个选项卡栏控制器(在注意到文档中的信息之前),然后发现在切换选项卡时开启和关闭导航栏会出现奇怪的行为。我希望选项卡控制器中的某些视图控制器有可见的导航栏,而其他一些则没有,但实际效果与预期完全不同(就像有一定的延迟,导航栏的隐藏和显示比预期晚了一个选项卡切换的时间)。所以我建议不要这么做。

文档中说你不应该这样做,你知道现在是否仍然有效,即不应该将UITabBarController放在UINavigationController或其他容器中吗?目前我无法在文档中找到这样的声明。 - Leszek Szary
1
@LeszekSzary 我找到了:https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621887-pushviewcontroller -“此对象不能是选项卡栏控制器”。 - Kuba Suder

1

0

最近我在开发一个应用程序,其中UITabbarController被推入UINavigationController中。这个应用程序目前已经在苹果商店上架。

我不知道为什么苹果不推荐这样做,以及为什么人们会遇到问题。

@Slashik的回答就是一个例子,我也是用了同样的方法。


0

我发现了一种情况,即在UINavigationController内部的UITabBarController不按预期工作。 重现错误的代码:

ViewController.swift

class ViewController: UIViewController {

   override func viewDidLoad() {
      super.viewDidLoad()
      navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(someSelector))
   }

}

SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

   var window: UIWindow?


   func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
      guard let windowScene = (scene as? UIWindowScene) else { return }

      let window = UIWindow(windowScene: windowScene)
      window.rootViewController = createRootViewController()
      window.makeKeyAndVisible()
      self.window = window
   }

   fileprivate func createRootViewController() -> UIViewController {
      let viewController = ViewController()
      let tabBarController = UITabBarController()
      tabBarController.viewControllers = [
         viewController
      ]
      let navigationController = UINavigationController()
      navigationController.pushViewController(tabBarController, animated: false)
      return navigationController
   }

我期望在右上角出现一个“添加”按钮。但最终,该按钮并未出现。然而,如果您将方法代码createRootViewController改写为以下内容:
let viewController = ViewController()
let tabBarController = UITabBarController()
tabBarController.viewControllers = [
   UINavigationController(rootViewController: viewController)
]
return tabBarController

然后出现“添加”按钮。

因此,如果您不想花费几个小时进行调试,最好遵循他们的建议。我不知道SDK的开发人员为什么没有在那里添加一个断言。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接