3
votes

I have gone through all the other posts about this topic but they don't seem to help me.

I have a UITabBarController that is launching two tabs. I want to pass data collected in tab1 to the UITabBar ViewController. I am trying to use delegete protocol for this but I am having trouble setting the delegate variable in the sending ViewController. The prepare for segue never gets called. I cannot even cycle through the viewcontrollers of the tabs inside the ViewDidLoad() of the Tabbar controller as they are not created yet and so nil.

I have used delegates before and it seems rather straightforward. Does it matter that I am using it in a Tabbar?

When I run the code the viewDidLoad() in TabBarViewController is called but not the preparefor segue.

The IBAction donePressed in the MeViewController is called but the delegate is not called as its not set.

Here is the code --

protocol DetailsDelegate: class {
    func myDetailsGathered( myDetails: MyDetails )
}

/// RECEIVING VIEW CONTROLLER

class TabBarViewController: UITabBarController, DetailsDelegate
{

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        print("prepare for segue called\n");

        if let destinationViewController = segue.destination as? MeViewController
        {
            destinationViewController.delegate = self
        }

    }

    override func viewDidLoad()
    {
        print("ViewDidLoad Called \n")
    }

    func myDetailsGathered(myDetails: MyDetails)
    {
        self.myDetails = myDetails
        print("My details gathered \n")
    }

}

---------------
/// SENDING VIEW CONTROLLER

class MeViewController: UIViewController
{
    weak var delegate: DetailsDelegate?

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    }

    // I have UIButton in the view and this is invoked when its pressed. 
    @IBAction func donePressed(_ sender: Any)
    {
        var infoToPass = MyDetails()

        print("looks like we are done")
        delegate?.myDetailsGathered(infoToPass: myDetails)
    }

}
2

2 Answers

0
votes

prepareForSegue is called when you perform a segue. Which you don´t do and that´s why it does not get called.

A segue defines a transition between two view controllers in your app’s storyboard file.

You should use a singleton class to store variables and access them between different controllers. You declare one like this:

class Singleton {
    static let sharedInstance = Singleton()
    var name = ""
}

Assign to Singleton:

Singleton.sharedInstance.name = "Some name"

To read from it from whatever controller:

let name = Singleton.sharedInstance.name
-1
votes

First of all, why do you want your tabbarController to receive some info/data though?

The prepare for segue never gets called.

prepareForSegue method will be invoked right after the performSegue. So where's your performSegue method? Or are you sure that that kind of segue going to MeViewController is being performed?

One more option you have is to use NotificationCenter.