iOS Storyboard 模态呈现标签栏 vs 推入 XCode 8

iOS Storyboard presenting tab bar modally vs push in XCode 8

考虑一个 storyboard,我们有 UITabBarController,其中嵌入了 UINavigationController 的任何 UIViewController(我们称它为 VC)。我们希望 VC 在其导航栏上有一个 BarButtonItems。这个故事板是由另一个故事板(有另一个导航控制器)的 push segue 呈现的。

XCode 一切正常,但 navigation bar does not change in VC at the runtime。然而,当我将这个故事板的呈现方式从推送更改为模态时,一切似乎都很好。恕我直言,这是因为嵌入了导航控制器,但我看不出它不工作的任何原因。任何想法如何合法地修复它(通过推送呈现)并且没有任何痛苦都会有所帮助。

提前致谢

所以我认为您将不得不使用一些代码来解决您的问题,但不会太多。我构建了一个测试项目来对此进行测试,并将附上图像和代码。 首先,如果我理解正确的话,你有一个 navigationController 推送有问题的新情节提要。见附图。

我命名了正在推送的故事板,因为这就是正在发生的事情。然后在我名为 Push 的情节提要中进行设置。

在 tabbarcontroller 的第一个视图控制器中,我添加了以下代码。显然,这隐藏了将我们推到这里的导航控制器。如果您随后访问 2 号控制器,我们会显示我们的新导航控制器和项目。如果将导航控制器隐藏在 tabbarcontroller 视图控制器 1 中不是你想要做的。继续阅读。

 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
   //or to unhide from returning the opposite ->self.parent?.navigationController?.isNavigationBarHidden = true
    self.parent?.navigationController?.isNavigationBarHidden = true
}

如果您不想在第一个视图控制器中隐藏导航控制器,但在访问控制器 2 时想要查看您的项目,则将其添加到您的 viewWillAppear 中,并在 viewWillAppear 的第一个控制器中将代码从 true 更改为假的。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // Do any additional setup after loading the view, typically from a nib.
    self.parent?.navigationController?.isNavigationBarHidden = true
}

这隐藏了父级导航控制器,因为它基本上覆盖了您示例中的导航控制器。所以上面隐藏了父导航控制器。这也是模态呈现有效的原因。您的导航控制器从一开始就被隐藏了。希望这可以帮助。

**编辑 如果你想要选项卡 2 视图控制器中的导航控制器,但你希望将父项保留在选项卡 1 中以便能够使用后退按钮返回,你可以在 viewWillAppear 中设置它,这样它在视图控制器 1 中看起来像这样。

 //tabcontroller vc 1
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.isNavigationBarHidden = false
}

在 tabcontroller view controller 2 和栏中的项目中,您可以执行此操作。 //tabbarcontroller vc 2 有自己的导航控制器 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(动画) self.parent?.navigationController?.isNavigationBarHidden = true }

最后,如果您希望后退按钮在两个控制器中都可见,但又想要不同的右按钮,请在 viewWillAppear 中以编程方式执行此操作

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
         self.tabBarController?.navigationItem.setRightBarButton(UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(FirstViewController.editSomthing)), animated: true)
}

如果你想在另一个控制器中删除它

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.tabBarController?.navigationItem.rightBarButtonItem = nil;
}

在上面的两个示例中,我们都保留了父导航控制器,因此您不需要将选项卡控制器的视图控制器嵌入到 uinavigation 控制器中。

如果您还想在 viewWillAppear 中使用 hide/show 父级导航控制器,您也可以使用上述代码的组合。其中一些取决于您现在和将来选择的视图层次结构。