简体   繁体   English

单击推送通知时,正确重定向到选项卡栏导航控制器内的视图控制器

[英]Properly redirect to a view controller inside tab bar's navigation controller when push notification is clicked

I have a tabBar .我有一个tabBar Each of its tabs' ViewControllers have been embedded inside their respective NavigationControllers .它的每个选项卡的ViewControllers都嵌入在它们各自的NavigationControllers

Hierarchy:等级制度:

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

I have to redirect to one of the viewcontrollers say VC2 when i click on push notifications.当我单击推送通知时,我必须重定向到其中一个视图控制器说 VC2。 The code i am using is as follows.我使用的代码如下。

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
}

By using this, I am redirected to the respective ViewController .通过使用它,我被重定向到相应的ViewController However, i am not able to get back to the tabBar .但是,我无法返回tabBar So is it possible to redirect in such a way that it allows me the get back to the tab bar, thus providing the same hierarchy as in the UI?那么是否有可能以允许我返回标签栏的方式重定向,从而提供与 UI 中相同的层次结构?

EDIT:编辑:

The image below shows my layout.下图显示了我的布局。

在此处输入图片说明

I would like to accomplish the following:我想完成以下工作:

  1. When the user taps the push notification, the app should be directed to VC-B.当用户点击推送通知时,应用程序应被定向到 VC-B。 *It should not create new object for VC-B and add to the navigation stack if VC-B is already on top of navigation stack. *如果 VC-B 已经在导航堆栈的顶部,它不应该为 VC-B 创建新对象并添加到导航堆栈。

  2. If the app had been terminated and the user taps on the notification, it should open VC-B.如果应用程序已终止并且用户点击通知,则应打开 VC-B。

For determining if the app had been terminated, I set a flag as:为了确定应用程序是否已终止,我设置了一个标志:

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

This flag is set false at the end of didFinishLaunchingWithOptions function.该标志在 didFinishLaunchingWithOptions 函数结束时设置为 false。

For redirection, I check this flag to determine if the app had been terminated:对于重定向,我检查此标志以确定应用程序是否已终止:

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)
            }     
        }
    }
}

With this code, my first requirement is partially fulfilled.使用此代码,我的第一个要求部分满足。 Need to determine if the viewcontroller is at the top of the navigation stack.需要确定视图控制器是否位于导航堆栈的顶部。

And, in the case of terminated app, clicking the push notification opens the tab bar, with the default selection index being selected.并且,在应用终止的情况下,单击推送通知会打开标签栏,并选择默认选择索引。

I have spent several days trying to fix this.我花了几天时间试图解决这个问题。 But cannot get it work.但不能让它工作。

I suppose you have to do something like this:我想你必须做这样的事情:

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)
    }
 }

Well, you are setting current window.rootViewController , which should be that TabBarViewController I'd say.好吧,您正在设置当前window.rootViewController ,这应该是我要说的TabBarViewController That's why you cannot get back to the TabBar这就是为什么你不能回到TabBar

What you should do is你应该做的是

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

To get the current navigation controller from the tabbar controller.从标签栏控制器获取当前导航控制器。 You can use this function你可以使用这个功能

 func getVisibleViewController(_ rootViewController: UIViewController?) -> UIViewController? { var rootVC = rootViewController if rootVC == nil { rootVC = UIApplication.shared.keyWindow?.rootViewController } if rootVC?.presentedViewController == nil { return rootVC } if let presented = rootVC?.presentedViewController { if presented.isKind(of: UINavigationController.self) { let navigationController = presented as! UINavigationController return navigationController.viewControllers.last! } if presented.isKind(of: UITabBarController.self) { let tabBarController = presented as! UITabBarController return tabBarController.selectedViewController! } //UIAlertController if presented.isKind(of: UIAlertController.self) { let alertController = presented as! UIAlertController return alertController.presentingViewController } return getVisibleViewController(presented) } return nil }

Using the function you can navigate your viewcontroller like below.使用该功能,您可以像下面一样导航您的视图控制器。

 let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let yourView = mainStoryboardIpad.instantiateViewController(withIdentifier: "yourView") as! NewnoteViewController let navi = self.getVisibleViewController(self.window!.rootViewController) as! UINavigationController navi.pushViewController(yourView, animated: true)

You can create a method in your RootViewController that will redirect user to a specific view after receiving a push notification.您可以在 RootViewController 中创建一个方法,在收到推送通知后将用户重定向到特定视图。 Here's what I did in my previous project.这是我在之前的项目中所做的。

class RootViewController: UIViewController {
    private var currentView: UIViewController
    
    init() {
        self.currentView = ViewController()
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        addChildViewController(currentView)               // 1
        currentView.view.frame = view.bounds              // 2
        view.addSubview(currentView.view)                 // 3
        currentView.didMove(toParentViewController: self) // 4
    }
    
    func showDetailsScreen() {
        if let updateDetailView = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "UpdateDetailsNotif") as? UpdateDetailsViewController{
            
            let navController = UINavigationController(rootViewController: updateDetailView)

            addChildViewController(navController)
            navController.view.frame = view.bounds
            view.addSubview(navController.view)
            navController.didMove(toParentViewController: self)
            currentView.willMove(toParentViewController: nil)
            currentView.view.removeFromSuperview()
            currentView.removeFromParentViewController()
            currentView = navController
        }
        
    }
   
}

Then you can call that method on your AppDelegate like this:然后您可以像这样在 AppDelegate 上调用该方法:

  func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let application = UIApplication.shared
  
        AppDelegate.shared.rootViewController.showDetailsScreen()
       
        completionHandler()
    
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 收到推送通知时如何显示嵌入在标签栏控制器中的导航控制器 - how to present a navigation controller embedded in a tab bar controller when receiving a push notification 如何将视图控制器推送到iOS中标签栏中的导航控制器 - how to push a view controller to a navigation controller in a tab bar in iOS 单击远程通知后能够重定向以指定视图控制器,但只有VC但没有导航栏 - able redirect to specify view controller after clicked remote notification but only VC but without navigation bar 在选项卡栏控制器中时,拆分视图控制器的导航栏较暗 - Navigation bar for split view controller is darker when inside a tab bar controller 标签栏未显示在导航控制器内的视图控制器上 - Tab Bar does not show on View Controller inside Navigation Controller 视图控制器的导航栏添加在标签栏控制器内导航控制器的导航栏下方 - Viewcontroller's navigation bar is added below navigation controller's navigation bar inside tab bar controller 在标签栏中推送View Controller - Push view Controller in the tab bar 投射标签栏控制器的导航控制器的可见视图控制器 - Casting a tab bar controller's navigation controller's visible view controller 在标签栏控制器内查看控制器 - View controller inside tab bar controller 从导航栏视图控制器导航到选项卡栏视图控制器 - Navigate from a navigation bar view controller to a tab bar view controller
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM