【问题标题】:How can I create a navigation stack with TabBarViewController as the root?如何创建以 TabBarViewController 为根的导航堆栈?
【发布时间】: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?

【问题讨论】:

    标签: ios objective-c swift


    【解决方案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(并将您随后的InstantMessagesViewControllers 推入此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 除了堆栈中的第一个)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 2021-06-01
    • 2015-04-13
    相关资源
    最近更新 更多