views:

271

answers:

3

I have a UIViewController — let's call it "FormController" — which is simply a form that edits an object. I want to use it in 2 different situations:

  1. Creating a new object — using using UINavigationController's presentModalViewController: method.

  2. Editing an existing object — push the view controller onto the UINavigationController stack, not using a dialog method.

There is a slight difference in that in the modal situation I would like to have a toolbar with "Cancel" and "Done" buttons, whereas in the stack situation I would like to just have the navigation bar provided by the UINavigationController.

This would be similar to the Contacts application where the "New Contact" and the "Edit Contact" screens seem to use the same view controller, but the New Contact form is presented modally while the Edit screen is pushed onto the navigation stack.

My question is: What is the best way to handle both situations without having to write 2 separate, but mostly identical view controllers?

I thought about creating a "ModalFormController" which encapsulates the bare "FormController" through composition and adds a toolbar, but I read somewhere in the docs that Apple doesn't recommend nesting view controllers.

+2  A: 

What I do (sometimes) is set up an enum that specifies the type of the view controller.

For example, you might have two types: an Edit type, and an Add ("new") type.

The Add type is implemented via a modal view controller, while the Edit type is pushed onto an existing navigation stack.

In the view controller's -viewDidLoad: method, I simply do a switch/case tree that sets up the title and other appearance characteristics depending on the type enumeration specified above.

The nice thing about this is that it is easy to add a new type. The downside is that the conditional tree for handing this enumeration can get complicated quickly, depending on how different the types are.

But the switch/case tree makes it a lot easier to manage.

So, it depends on what you're trying to do with the two types. But it's definitely doable.

Alex Reynolds
Thanks Alex. I think all answers were valid but after some deliberation I'm going to go in the direction that you set. I'm just going to use a BOOL that knows whether the FormController is being displayed modally.
Sam
+2  A: 

Why not use subclassing? Make ModalCreateFormController a subclass of EditFormController and handle the modal-specific stuff in the subclass.

Ole Begemann
I thought about that too. Maybe I will try that next time...I had a really hard time deciding which way to go.
Sam
+2  A: 

In addition to having an explicit property on the view controller (as Alex Reynolds suggests), two other approaches that occur to me are:

  1. If you have some kind of model object that you're editing, ask it for its current state. If it's ever been saved, then you're in edit mode. Otherwise, you're in create mode.

  2. Look at the value of the controller's parentViewController property. If it's an instance of UINavigationController, then you're in the navigation stack. If you're being displayed modally, it'll be an instance of your list controller.

Sixten Otto
Thanks Sixten. I'm going to use that idea in #2 in conjunction with Alex's answer above.
Sam