Thromordyn
Thromordyn

Reputation: 1581

Dismiss multiple modal views without a navigation controller

I didn't plan ahead properly for view navigation in my app, so it's possible for the user to go through a loop that just stacks modal views on top of each other, and from there the root view controller is only accessible through the time-consuming process of manually dismissing each and every repeated view.

I can't just go ahead and use popToRootViewControllerAnimated: without a navigation controller on top of it all (calling presetModalViewController:animated: repeatedly seemed like a good idea at the time), so unless there's something Google is hiding from me, I'm completely lost.

Rewriting half the navigation code is not ideal, but if that really is the only option, I'll give it a shot.
Avoiding that would certainly be preferable.

No idea what code would be helpful, if any. It's just presenting/dismissing modal view controllers with a few subclasses of UIViewController

Upvotes: 3

Views: 1581

Answers (4)

Thromordyn
Thromordyn

Reputation: 1581

Okay, now I got it. Below the line is what I should never have done. Rather than trying to contain a loop-grown stack, I should have just blocked it to begin with.

That is, the "Load" button no longer spawns another view. Instead, it dismisses the current view, which can only ever be a child of the Load view, giving the illusion of a new view and completely removing the problem of an uncontrollably growing stack.


Again, this is the wrong option:

A global, a few #define'd strings, and some if/else stacks, and the lack of a navigation controller is not a problem.

If anyone is interested in what I've done to achieve this (and/or how much fun it'll be to modify later), I'll drop some of the it into this answer. It's not pretty and it was a pain to write (mostly because the new code spans four files and breaks quietly), but it does exactly what I want.

Upvotes: 0

Caleb
Caleb

Reputation: 124997

Both @Grady's answers are the right ones. A look at the documentation for -dismissModalViewController:animated: tells you:

If you present several modal view controllers in succession, and thus build a stack of modal view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack.

You should use -dismiss... rather than popping the controller from the nav stack, since modal controllers may not even be part of the navigation stack. Nevertheless, if you find that your app should have been a navigation-based app, then just take the time to make it so. If that's a lot of work, it's probably work that needs to be done anyway.

Upvotes: 1

Grady Player
Grady Player

Reputation: 14549

answer A: easy answer;

just call dismissModalViewController:animated: on the view that you want to see.

answer B: real answer;

It will not be hard for you to re-factor as a Navigation Controller app, I would start a new project that is a Navigation app, and look at the methods in the application delegate, and emulate that behavior.

then when you would normally present, just push ([self.navigationController pushViewController: controller animated: YES]) and your dismiss will become a pop ([self.navigationController popViewControllerAnimated: YES])

Hope that helps

Upvotes: 2

Víctor B.
Víctor B.

Reputation: 1680

Change the view property in your UIViewController doesn't work?

Upvotes: 0

Related Questions