Pass Data between two View Controller

I have two View Controller, lets call them A1 and A2. A1 has consits of a tableView with various entries. If I click on an entry namend "Orange" in A1, A2 should show details about Orange. To store the data I use Core Data. I filter the data I need for the Orange in A1 and now I want to pass the data like name, size etc. to A2. I tried to use a function in A1 wich sets the variables in A2. This works but when I perform the segue all the data is gone. What can I do to pass the data?
Code Block
func initializer(caption: String, size : String, text: String) {
        self.text = text
        self.fruitCaption = caption
        self.fruitSize = size
    }

I call this initializer function from A1, the function itself is placed in A2.


Answered by Claude31 in 653090022
I fear you are doing it improperly.

you create
Code Block
        let vc =  ThirdViewController()


but the segue will instantiate another ThirdViewController.
And you loose everything you have passed to vc which is deleted when exiting the func.

So you should:
  • define a prepare for segue func

  • include the preparation code in it, but NOT create instance of ThirdViewController

  • just call if let vc = segue.destination

Code Block
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueID" {
if let destVC = segue.destination as? ThirdViewController {
destVC.caption = caption
// Do the same with all properties
destVC.fruitCaption = caption
destVC.fruitSize = size
}
}
}


I call this initializer function from A1

When and where are you calling this function?
I call this function right before I perform the segue with code
Code Block
// function with code for loading the data from core data
print("loaded  " + caption)
                    self.caption = caption
                    self.size = size as! String
                    self.text = text as! String
                }
            }
            print ("fertig")
        } catch  {
            print(error)
        }
        let vc =  ThirdViewController()
        vc.initializer(caption : caption, size : size, text : text)
//        Segue wird ausgeführt
        performSegue(withIdentifier: "shownext", sender: indexesToRedraw)
    }


Accepted Answer
I fear you are doing it improperly.

you create
Code Block
        let vc =  ThirdViewController()


but the segue will instantiate another ThirdViewController.
And you loose everything you have passed to vc which is deleted when exiting the func.

So you should:
  • define a prepare for segue func

  • include the preparation code in it, but NOT create instance of ThirdViewController

  • just call if let vc = segue.destination

Code Block
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueID" {
if let destVC = segue.destination as? ThirdViewController {
destVC.caption = caption
// Do the same with all properties
destVC.fruitCaption = caption
destVC.fruitSize = size
}
}
}


Thank you now it works!
(Do not worry, seems I'm too late.)

I call this function right before I perform the segue with code

Thanks for showing the code. (So, ThirdViewController is A2, OK?)

The worst thing in your code is this line:
Code Block
        let vc =  ThirdViewController()


Instantiating a view controller with init() is almost always a bad idea and would not work as expected.
Especially when the transition is made through a segue, it is iOS to create a new instance, not you.
The instance held in vc of your code is disposed soon after you called initializer(caption:size:text:), and another instance created by iOS will be presented.


You need to call initializer(caption:size:text:) for the right instance.
You can get the right instance in prepare(for:sender:).
Code Block
... {
//...
// Remove the following two lines...
//let vc = ThirdViewController()
//vc.initializer(caption : caption, size : size, text : text)
// Segue wird ausgeführt
performSegue(withIdentifier: "shownext", sender: indexesToRedraw)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "shownext" {
let vc = segue.destination as! ThirdViewController //<- `segue.destination` is the right instance
vc.initializer(caption: self.caption, size: self.size, text: self.text)
//...
} else {
//...
}
}



You need to use the passed values at the right place, but I cannot see if you are doing it correctly or not.
Pass Data between two View Controller
 
 
Q