Rich Rich - 3 months ago 18
Objective-C Question

Programmatically navigating in iOS

I'm in the process of porting an existing Android app to iOS, and I'm pretty inexperienced in this environment. The examples I've read so far for navigating multiple views all use some kind of visual user control for triggering the loading and unloading of views (tab bar, nav bar). This application's navigation needs to be pretty strict and not allow the user to freely move around between the three views.

The app needs to have a full screen splash view, a main view that the user interacts with, and a third view for data collection. The splash screen should appear, and the user should be navigated to the main view when tapping on the splash image. There will be custom logic in the main view controller for determining if data is required at which point it should navigate to the data collection view. Once valid data is entered and the user clicks OK, it should navigate back to the main view.

What I've read so far is that all Views should have an associated UIViewController class, and the easy way to do this is to create the XIB and UIViewController class in one shot and link them together (I have plenty examples/books/tutorials that I can reference for that part). I believe what I've read is that the app should have a root UIViewController that handles loading the others and navigating between them.

My questions are:
What class should I derive from for my main view controller that I use to load the others?
How do I wire that up to the app so that it knows to load this as the main controller?
What is the accepted standard way of having a navigation controller in the app and allowing the other views to obtain a reference to it? Should my UIViewControllers hold a reference to their parent controller, or should they ask the UIApplication for a reference to it when needed? How do I make sure I don't instantiate extra copies of the views and their controllers as the user navigates?

Answer

What class should I derive from for my main view controller that I use to load the others?

UIViewController

How do I wire that up to the app so that it knows to load this as the main controller?

Read the "Defining Your Subclass" section of View Controller Programming Guide for iOS. Scratch that -- read the whole thing. It's all important, you might as well start to learn it now. Also read App Programming Guide for iOS. Again, read the whole thing, but the application lifecycle part is the most relevant to your question.

What is the accepted standard way of having a navigation controller in the app and allowing the other views to obtain a reference to it?

Again, this is explained well in View Controller Programming Guide. Views should never care about the navigation controller, but any view controllers that are part of a navigation stack have direct access to the nav controller via their respective navigationController properties.

Should my UIViewControllers hold a reference to their parent controller, or should they ask the UIApplication for a reference to it when needed?

A view controller already has a reference to its parent controller in its (surprise!) parentController property. It's best for a controller to avoid assuming too much about its parent, though. If the controller expects its parent to be a certain type or respond to certain messages, it becomes more difficult to reuse that controller or reorganize your application. Try to give the controller what it needs to do its thing when you create it. If the controller will need to ask for additional data or something like that, delegation is a good way to go.

How do I make sure I don't instantiate extra copies of the views and their controllers as the user navigates?

Exercise caution. There's not much danger of creating extra copies of views in a properly structured application because each view controller should take care of its own views. If you find yourself loading or otherwise creating views outside the context of the view controller that owns them, stop that.