如何创建以 TabBarViewController 为根的导航堆栈?
Posted
技术标签:
【中文标题】如何创建以 TabBarViewController 为根的导航堆栈?【英文标题】:How can I create a navigation stack with TabBarViewController as the root? 【发布时间】:2016-02-15 02:29:22 【问题描述】:我的 TabBarVC 是我的应用程序的核心。我有 3 个视图控制器。每个视图控制器都“嵌入”在导航控制器中。
TabBarVC -> UINavigationController -> HomeVC
-> UINavigationController -> TimelineVC
-> UINavigationController -> ConversationVC
我希望我的TabBarVC
能够随时将InstantMessageViewController
推送到它的堆栈上。我知道 TabBarVC 没有“堆栈”或 NavigationController - 只有它的子级才有导航控制器。
当TabBarVC
收到NSNotification
时,我想将InstantMessageViewController
推入其堆栈。
TabBarVC
里面可能有这样的东西?
let mvc = self?.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! InstantMessagesViewController
mvc.user = self?.notificationUser
self?.navigationController?.pushViewController(mvc, animated: true) //it doens't work because self.navigationController is nil.
当用户按下返回按钮时,它会返回到 TabBarVC。
我希望能够随时将多个InstantMessagesViewController
推入堆栈并以编程方式重新排序。
我不知道什么是最好的方法。我要创建一个 UIWINdow 吗?我是否以编程方式创建 UINavigationController?
【问题讨论】:
【参考方案1】:您可以做的一件事是将InstantMessagesViewController
推送到当前在UITabBarController
上选择的UINavigationController
。
// Inside your UITabBarController
if let navigationController = selectedViewController
let mvc = self?.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! InstantMessagesViewController
mvc.user = self?.notificationUser
navigationController.pushViewController(mvc, animated: true)
但正确的做法是以模态方式呈现InstantMessagesViewController
(并将您随后的InstantMessagesViewController
s 推入此UINavigationController
堆栈):
let mvc = self?.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! InstantMessagesViewController
mvc.user = self?.notificationUser
let navController = UINavigationController(rootViewController: mvc)
presentViewController(navController, animated: true, completion: nil)
要在您的根目录InstantMessagesViewController
上关闭此UINavigationController
,请在InstantMessagesViewController
中尝试以下代码:
override func viewDidLoad()
super.viewDidLoad()
if let navigationController = navigationController
if navigationController.viewControllers.count == 1
let barButton = UIBarButtonItem(title: "Back", style: .Plain, target: self, action: "onBackTapped:")
navigationItem.leftBarButtonItem = barButton
func onBackTapped(barButtonItem: UIBarButtonItem)
dismissViewControllerAnimated(true, completion: nil)
【讨论】:
我不想将它推送到 selectedViewController 上,因为它与那个视图控制器无关。 (它们是不同的概念)。我知道模态是正确的方法,但我需要管理堆栈并让用户来回导航。 我已经更新了我的答案,以包含您以模态方式呈现的 UINavigationController。这将为您提供所需的导航堆栈,并且当您单击后退按钮(您必须添加)时,根消息控制器可以关闭 navController。 谢谢马克。我的根 VC 如何关闭 navController 模式? 我已经更新了我的答案以包含您可以添加到InstantMessagesViewController
以添加自定义后退按钮的代码。
非常感谢。你知道为什么当根 VC 试图解散时 deinit 没有被调用吗? (堆栈中的所有其他调用 deinit 除了堆栈中的第一个)以上是关于如何创建以 TabBarViewController 为根的导航堆栈?的主要内容,如果未能解决你的问题,请参考以下文章