ios - 单击推送通知时正确重定向到选项卡栏导航 Controller 内的 View Controller

标签 ios swift push-notification uinavigationcontroller uitabbarcontroller

我有一个tabBar。它的每个选项卡的 ViewControllers 都已嵌入到各自的 NavigationControllers 中。

层次结构:

Tabbarcontroller --> NavigationController --> VC1 --> VC2 -->...VCn (for tab1)

当我点击推送通知时,我必须重定向到其中一个 View Controller 说 VC2。我使用的代码如下。

let navigationController = UINavigationController()
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
if let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as? ChatViewController {
    navigationController.viewControllers = [chatViewController]
    window?.rootViewController = navigationController
}

通过使用它,我被重定向到相应的 ViewController。但是,我无法返回到 tabBar。那么是否有可能以允许我返回选项卡栏的方式进行重定向,从而提供与 UI 中相同的层次结构?

编辑:

下图显示了我的布局。

enter image description here

我想完成以下任务:

  1. 当用户点击推送通知时,应将应用定向到 VC-B。 *如果 VC-B 已经在导航堆栈的顶部,它不应该为 VC-B 创建新对象并添加到导航堆栈。

  2. 如果应用已终止并且用户点击通知,它应该打开 VC-B。

为了确定应用程序是否已终止,我将标志设置为:

func applicationWillTerminate(_ application: UIApplication) {
    UserDefaults.standard.set(true, forKey: UserDefaultsKey.isTerminated)
}

此标志在 didFinishLaunchingWithOptions 函数结束时设置为 false。

对于重定向,我检查此标志以确定应用程序是否已终止:

func performRedirectionToSuitableViewController(userInfo: [AnyHashable: Any]) {
  
    let isTerminated = UserDefaults.standard.object(forKey: UserDefaultsKey.isTerminated) as! Bool
    
    if isTerminated {
        
        let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
        
        let tab = storyboard.instantiateViewController(withIdentifier: "tabBar") as! UITabBarController
        
        tab.selectedIndex = 0
        
        let nav = tab.viewControllers![0] as! UINavigationController
        
        let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as! ChatViewController
        
        chatViewController.chatThreadId = userInfo["thread_id"] as? String
        
        nav.pushViewController(chatViewController, animated: true)

    } else {

        if let tab = window?.rootViewController?.presentedViewController as? UITabBarController {

            let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)

            let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as! ChatViewController
                
            chatViewController.chatThreadId = userInfo["thread_id"] as? String
               
            if let nav = tab.selectedViewController as? UINavigationController {
                   
                nav.pushViewController(chatViewController, animated: true)
            }     
        }
    }
}

有了这段代码,我的第一个要求就部分满足了。需要判断 viewcontroller 是否在导航栈的顶部。

并且,在终止应用程序的情况下,单击推送通知会打开选项卡栏,并选择默认选择索引。

我花了几天时间试图解决这个问题。但无法让它工作。

最佳答案

我想你必须做这样的事情:

let tabBar: UITabBarController // get your tab bar
tabBar.selectedIndex = 0 // eg. zero. To be sure that you are on correct tab
if let navigation = tabBar.viewControllers?[tabBar.selectedIndex] as? UINavigationController {
    let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
    if let chatViewController = storyboard.instantiateViewController(withIdentifier: "chatViewController") as? ChatViewController {
        navigation.pushViewController(chatViewController, animated: true)
    }
 }

关于ios - 单击推送通知时正确重定向到选项卡栏导航 Controller 内的 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51762691/

相关文章:

ios - 如何同步2个不同层的动画

ios - 如何在另一个 View 上方显示 PickerView

ios - 没有相应委托(delegate)方法的 UIApplicationBackgroundRefreshStatusDidChangeNotification 用法

swift - 在 TableViewCell 中按下标签时关闭 View

ios - 使用 bluemix for ios 的静默远程通知

ios - Swift:创建具有不同自定义类型的数组

ios - 使用 RxSwift 处理请求时出错

swift - 如何在 Swift 中使用 UILongPressGestureRecognizer 通过标签属性传递 indexPath.row?

android - OneSignal.setSubscription(true) 不适用于 Android?

java - Firebase 推送 - 身份验证凭据无效