从 UITabBarController 内部呈现 UINavigationController

Posted

技术标签:

【中文标题】从 UITabBarController 内部呈现 UINavigationController【英文标题】:Present UINavigationController from inside UITabBarController 【发布时间】:2017-12-26 03:07:46 【问题描述】:

我有一个关于从我的 AppDelegate 实例化特定视图控制器的快速问题。我正在构建一个简单的聊天应用程序,当用户通过远程通知打开应用程序时需要响应。我的应用程序期望的行为是,当用户点击此通知时,应用程序将打开到该特定聊天屏幕。

应用的基本流程如下:

***别的 UI 组件是 UITabBarController 这个标签栏里面是一个导航控制器 导航控制器内部是一个视图控制器(我们称之为“列表”),它列出了所有可用的聊天窗口 一旦用户点击我的表格视图中列出聊天的行之一,就会推送一个新的视图控制器。这个视图控制器是聊天窗口,它会自动隐藏标签栏,但保留导航控制器的后退按钮 当用户点击返回按钮时,它将返回到聊天列表,标签栏将重新出现

我正在使用以下代码来显示正确的聊天屏幕。我可以点击返回按钮,它会按预期返回到聊天列表。唯一的问题是导航控制器没有嵌入到选项卡控制器中。这段代码是从func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler调用的:

let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialVC : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "ChatVC") as UIViewController
let detailVC : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "ChatDetailVC") as UIViewController
let navContr = UINavigationController(rootViewController:initialVC)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = navContr
self.window?.makeKeyAndVisible()
initialVC.navigationController?.pushViewController(detailVC, animated: true)

如何配置我的代码以使选项卡控制器成为堆栈的顶层?它在我的故事板中被标记为“TabController”。

【问题讨论】:

当用户点击通知时,您需要手动执行每个导航。 试试this 【参考方案1】:

你只需要创建一个 flag 来确定用户是来自通知点击还是正常启动

struct NotificationEvent 
    static var isFromNotification = false

控制器的堆栈是-

TabBarController->UINavigationController->ChatListViewController->ChatDetailViewController

在 AppDelegate func userNotificationCenter -

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "TabViewController") as! TabViewController//Your Tabbarcontroller
NotificationEvent.isFromNotification = true//recognize is from notification 
window?.rootViewController = vc

ChatListViewController

class ChatListViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        if NotificationEvent.isFromNotification  
            openChatDetailScreen()//Jumps to that chat screen
            NotificationEvent.isFromNotification = false
        
    
    @IBAction func tapsOnChatList(_ sender: UIButton) //consider it as didselect method in your tableView
        openChatDetailScreen()
    

    func openChatDetailScreen() 
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "ChatDetailViewController") as! ChatDetailViewController
        navigationController?.pushViewController(vc, animated: true)
    

代替NotificationEvent.isFromNotification,您还可以使用UIApplicationLaunchOptionsKey.remoteNotification/observer 来检查特定视图控制器中的通知事件。

【讨论】:

以上是关于从 UITabBarController 内部呈现 UINavigationController的主要内容,如果未能解决你的问题,请参考以下文章

从 UITabBarController 选项卡根视图呈现 UINavigationController

从 uitabbarController 视图中关闭模态视图

无法从模态 ViewController 访问 UITabBarController

在 UITabBarController 中呈现模态视图

在 UITabBarController 中呈现一个新的 UIViewControler

在 UITabBarController 之前呈现登录视图控制器