This had me up for a few nights, so here is my solution. I think someone at #iosDevCamp asked me this same question, too – I think it was Sophia.
Problem: You have an iPhone app with a UIRootViewController, tab navigation, with a UIButton that launches a UITableViewController (a second view). When a user selects a row in the table, and you want that action to affect something on the RootViewController.
Real world example: My main root view controller has a movie player (UIMoviePlayerViewController). When a user selects the button on the tab “movies,” I want that selected movie to start playing back in the root view controller, and collapse the current table view. The code for starting the movie is in the RootViewController, so I need to pass it the command to start playing, and the name of the movie.
The way that works for me is:
Setup a method in the root view controller.
// all the movie goodness here
In my UITableViewController’s “did select”, I access the Root ViewController through… wait for it… took me forever to figure this out… the NavigationController.
[[self.navigationController.viewControllers objectAtIndex:0] didTap];
Some crafty things: the root controller will always be the first in the array, “viewControllers.” “Pop to root” is a convenient way to slide the tableview off and display the movie again. I actually read the Class documentation for that one!
On the iPad, I can simply refer to it as [appDelegate.viewController didTap] (Thanks to Scott Tran for that simple, so seemingly obvious, way of doing it). The Navigation/Tab stuff complicates things, I take it.
How do you pass an object?
There are various ways. I chose to setup a property in the app delegate, and set that value from the tableviewController, so I didn’t pass it along to the RootViewController with the method, but you could:
I’d like to also say- you can setup a NSNotification, which is quite easy and works.
I realize it’s a bit controversial to access a method in another UIViewController. Best design sense says to build it in the appDelegate and refer to that from each view. I was 90% done with this app and not interested in refactoring.