0

I'm trying to set the currentVC as the delegate for the destinationVC that is being navigated to through a UITabBarController and embedded in a UINavigationController.

I cant set the current VC as the delegate because prepareForSegue never gets triggered and the other solutions provided doesn't work either (bottom code).

This was all set up as Storyboards with Interface-builder

This is the architecture:

--> UITabBarController

-->UINavigationController

--> currentVC (Set this as the delegate)

-->UINavigationController

--> destinationVC

This does nothing:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

   print ("The Segue was triggered")
   let destinationVC = segue.destination as! MyViewController
   destinationVC.delegate = self

}

I also cant get this to work (it never goes through the IF statement):

override func viewDidLoad() {
        super.viewDidLoad()

        if let myDestinationVC = (self.tabBarController?.viewControllers![0] as? UINavigationController)?.viewControllers[0] as? destinationVC {
            print ("The IF statement was triggered")
            myDestinationVC.delegate = self
        }
}

I have a custom class for my TabBarController, that doesn't really do anything right now - I'm not sure if I need to reference that in the code above?

Brewski
  • 654
  • 3
  • 14
  • 29
  • How are you displaying the destinationVC? If it's a tab on the tab bar, then the architecture you provided isn't correct as the destinationVC would not be on the UINavigationController's view stack. – clawesome Dec 18 '19 at 14:33
  • You are right, I updated the architecture to reflect this. Each have their own UINavigationController. @clawesome – Brewski Dec 18 '19 at 14:38
  • Are the destinationVC and currentVC on the same tab or different tabs? – chickenparm Dec 18 '19 at 15:30
  • Same tabbarcontroller - different “tabs” @chickenparm – Brewski Dec 18 '19 at 15:31
  • Are you sure a delegate is the best solution here? What are you trying to pass between these view controllers? – chickenparm Dec 18 '19 at 15:37
  • @chickenparm I want to call a function that stops the loader from showing in currentVC when data is done uploading to Firebase on the destinationVC – Brewski Dec 18 '19 at 15:40
  • Check out this question here: https://stackoverflow.com/questions/27651507/passing-data-between-tab-viewed-controllers-in-swift – chickenparm Dec 18 '19 at 15:48
  • I've already tried that and I get: Could not cast value of type 'UINavigationController' to 'Project.DestinationVC' @chickenparm – Brewski Dec 18 '19 at 16:02
  • @Brewski That's because the controller at `self.tabBarController?.viewControllers[1]` in your case is a `UINavigationController`. You would need to to use `if let navController = self.tabBarController?.viewControllers[1] as? UINavigationController, let destinationVC = navController.viewControllers.last as? DestinationVC { ... }` – clawesome Dec 18 '19 at 21:16

1 Answers1

0

Here is a working and tested implementation. Not the best way to accomplish this, but will work for what you've described.

class MyTabBarViewController: UITabBarController, UITabBarControllerDelegate {

    // Replace with your sending view controller class's type
    var sendingViewController: SendingViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self

        // Iterate all view controllers to make sure they are instantiated and
        // get reference to the sendingViewController
        viewControllers?.forEach {
            if let navigationController = $0 as? UINavigationController {
                // Replace with the type of your sending view controller
                if let sendingViewController = navigationController.topViewController as? SendingViewController {
                    self.sendingViewController = sendingViewController
                }
            }

        }
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {

        if let navigationController = viewController as? UINavigationController {
            // Replace with the type of your receiving view controller
            if let receivingViewController = navigationController.topViewController as? ReceivingViewController,
                let sendingViewController = sendingViewController {
                // Perform actions here
                receivingViewController.view.backgroundColor = sendingViewController.view.backgroundColor
            }
        }
    }
}
clawesome
  • 1,223
  • 1
  • 5
  • 10
  • I tried but can't get it to 'trigger', is there a way to include your code in my existing tabBarController code which uses tags (I tried removing mine and still could not get yours to work): override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { – Brewski Dec 19 '19 at 06:42
  • Look at the method I used in this example, it uses `didSelect viewController: UIViewController` – clawesome Dec 19 '19 at 07:01
  • If you still can't get the callback or 'trigger' then your delegate must be improperly set. – clawesome Dec 19 '19 at 15:22