Note: This is Scott’s first article for Tech Tails. Scott works in our Waitsfield, VT location in the IT department as a developer. He’s one smart cookie, so be on the lookout for future articles from him!
I was recently developing a simple iOS application based on a single view controller managing two scenes in a storyboard. The main goal was to have a form in two parts — one on the first scene, and the next on the second scene. After collecting the form data from the first scene’s form, I needed to collect the rest from the second scene and then submit the whole package up to a server.
The problem was in getting the partial data from that first scene to be available in the second scene. Looking at some tutorials, it seemed like the correct way to do this is to attach onto the prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender method and basically grab the data from the departing scene and push it along to the second scene. Unfortunately, every single tutorial I read had the setup of two separate view controllers. So in leaving the first scene, you were also leaving one view controller. It made sense in some of the tutorials to have two view controllers, but there were others where it didn’t make any sense at all. My project certainly didn’t need a second view controller. It was just one form split into two scenes to make for a better user experience.
At first, I thought I could simply create a member variable for my single view controller and just set it to the departing form’s data. This frustratingly does not work. The reason is because in transitioning to the new scene via the segue, a totally new view controller instance is created. In my case, this was a bit confusing because it was still the same view controller that was being created. The original instance, where the prepareForSegue method is running, is lost. So anything you store in it will be lost as well.
The solution is the same as if you had a different view controller managing that second scene. Within the prepareForSegue method, you can grab a handle to this new view controller instance by calling [segue destinationViewController]. It’s this view controller object that will be used with the second scene, so you need to set any member variables on it. When the second scene loads, the controller running it will have all the data you set before running the segue.
This process still feels a bit counterintuitive, since it seems like there should only ever be one instance of the view controller running the entire show unless a scene with a new view controller is loaded. I’m convinced that using a single view controller in my project is the right thing to do, and passing the data through the segue should be fine. And to all those tutorials out there: Don’t use extra view controllers unless you really need to and there’s a good functional reason for doing so.