After writing my previous post on adding an iOS container view, I received a couple of questions about how to pass data to the container view. This is a great question because the answer is not obvious to a person just learning iOS. In this post, I will show you how to keep a reference to your container view’s view controller to pass data or call functions on it.
Segues for Different Purposes
When you think of segues, you may think they are only for transitioning from one scene in your storyboard to another. In this diagram, we are using show segues to transition from one top-level view controller (scene) to another.
What we learned in my previous post was that segues can also be used to embed container views in your view controller.
We are going to take advantage of the fact that iOS treats all segues the same in order to solve our problem.
Prepare for That Segue
One of the functions you can override in your view controller is prepareForSegue
. It is commonly used to pass data from one view controller to another for a show segue.
In that case, it is called just before you make the transition from one scene to another. In the moment before the transition, both view controllers exist in memory. The prepareForSegue
allows you to get a reference to the destination of the transition and pass any data along to the next view controller.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "TransitionToSecondViewController") {
let secondViewController = segue.destinationViewController as! SecondViewController
// Pass data to secondViewController before the transition
}
}
But what about embed segues and container views? Though it may not be obvious to people learning iOS, this function is also called to prepare for the embed segue that happens when a parent view controller contains a container view. In this situation, the destination view controller is the child view controller of your container view.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "myEmbeddedSegue") {
let childViewController = segue.destinationViewController as! myChildViewController
// Now you have a pointer to the child view controller.
// You can save the reference to it, or pass data to it.
}
}
After prepareForSegue
has been called, you can optionally store the reference to the child view controller in a property on your view controller. We can be assured that the lifecycle of the child view controller will remain as long as the parent view controller is alive.
Name That Segue
You can tell from my code samples above that I am checking to see if the segue matches an identifier. Because prepareForSegue
can be called for different types of segues, we need to make sure we are operating on the segue we are interested in.
To identify a segue, in interface builder, click on a segue and give it a storyboard identifier in the attribute inspector.
Timing of prepareForSegue
My last piece of advice is to keep in mind that the view for the destination view controller is not loaded when prepareForSegue
is called. This is true for all types of segues. The viewDidLoad function has not been called yet for your child view controller. Therefore, you cannot directly manipulate UI elements on the destination view controller inside the prepareForSegue
function. It is better to set some state property on the child view controller and let it configure itself properly when its own viewDidLoad is called.
Catch up on my other posts in this series:
- Adding an iOS Container View in Xcode
- How to Pass Data to an iOS Container View
- The Easy Way to Switch Container Views in iOS
- Switching Child View Controllers in iOS with Auto Layout
For more on using Xcode, read my series on unwind segues:
How do i save the reference to child view controller ?
Thanks
re: Long Tran
just declare it at the top of your parent view controller… something like this:
var vc: HomeContainerController? = nil
then in your prepareforsegue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
vc = segue.destination as! HomeContainerController
}
Now you can use ‘vc’ throughout your parent view controller
How do you call a function that resides in the UITableViewController from the ViewController which holds the container with the UITableViewController. Assume that in UITableViewController you have a function with some logic and based on the result of that function when you call it from your ViewController (which again holds your container and the UItableViewController) you want to segue to a completely different scene. My question is here http://stackoverflow.com/questions/42600534 . Many thanks
Oh man i have been looking for this for a week , finally got it :)
thank you ,