tags:

views:

154

answers:

3

I'm making a set of screens similar to a wizard and I'd like to know how to make a view dismiss itself and its parent view and immediately show a 'DoneScreen' without worrying about resource leaks. My views look like the following:

Base -> Level1 -> DoneScreen
               -> Level2 -> DoneScreen

The Level1 controller is a navigation controller created with a view.xib and shown with

[self presentModalViewController ...]

by the Base controller. The Level1 controller is also responsible for creating the 'DoneScreen' which may be shown instead of the Level2 Screen based on a certain criteria.

When the user taps a button on the screen, the Level1 controller instantiates the the Level2 controller and it displays it via

[self.navigationController pushViewController ..]

and Level2 controller's view has a 'Next' button.

When the use hits the 'Next' button in the Level2 screen, I need to dismiss the current Level2's view as well as the Level1's view and display the 'DoneScreen', which would have been created and passed in to the Level2 controller from Level1. (partly to reduce code duplication, and partly to separate responsibilities among the controllers) In the Level2 controller, if I show the 'DoneScreen' first and dismiss itself with

[self.navigationController popViewControllerAnimated:YES];

then the Level1 controller's modal view is still present above the 'Base' but under the Done screen. What's a good way to clear out all of these views except the Base and then show the 'DoneScreen'?

Any good suggestions on how to get this done in a simple but elegant manner?

A: 

A google search for "iphone wizard tutorial" only yielded one good result. It looks like it might be a better idea for now to make one long view containing all your wizard screen widgets.

mcandre
The caveat this that the Level1 through DoneScreen portions need to be reused within the same project which is why I didn't go the 'everything in a single view' route.
Robin Jamieson
I thought I could use the "Chain of Responsibility" pattern here and pass in the 'next' controller to the Level2 from Level1. But whatever I pass into Level2 has to be stored and then right before it is dismissed with popViewControllerAnimated, I could show the next screen -- the question is whether this would cause some sort of circular reference/memory leaks since the dismissal Level2's view would cause its own controller would start to get cleaned up but it won't since the 'DoneScreen' is still being shown.
Robin Jamieson
A: 

You could consider grabbing the views you want in the stack, making a new array then using the navigation controllers "viewControllers" property to swap them all out at once.

criscokid
I tried that but I didn't see the 'DoneScreen' as I had expected. Instead, I'm back at the 'Level1' screen.
Robin Jamieson
I take it back -- only the title bar area of the 'DoneScreen' is shown while the content area is still that of 'Level1'. Right after I swapped the controller, I did a check on the count of view controllers and the count yielded 0.. (NSArray *controllers = [NSArray arrayWithObjects:self.nextController, nil]; [self.navigationController setViewControllers:controllers animated:NO]; viewControllers = [self.navigationController viewControllers];
Robin Jamieson
Oh sorry I get what you are saying now, didn't notice level one was presented as modal.
criscokid
A: 

Alas, my depth of knowledge (or lack of) has led me to go to the single screen with everything on it route, using multiple views depending on the state. Not ideal and a bit messier but it works. Thanks all for your help.

Robin Jamieson