Lets say you present modal view controller (which is navigation controller) and push onto navigation stack 3-4 view controllers. Would dismissing modal view controller also pop these controllers from navigation stack, or will they continue to linger in memory?
I apple doc it states that when presenting multiple modal view controllers, if you dismiss the root one, all other will be dismissed, but animation of dismissal will happen only once. There is, however, no mention, what if you had pushed some controllers on modal view controller and then dismissed it.
When you dismiss the modal view controller, it will be deallocated from memory. So unless you keep a reference to it, everything will be removed, including its inner view controllers in the stack.
However, if you do keep a reference to it, it will stay alive when dismissed, therefore keeping its current state. Next time you present it, it will be just as you left it.
The navigation controller contains the view controllers that are pushed within it. So when the navigation controller is presented modally and then dismissed, it's (contained) view controller stack gets cleaned up, too.
Related
I'm working on a project which has multiple view controllers stacked in a navigation controller, similar to this:
https://youtu.be/yl2m4fDOLQo
I fear that I may end up stacking too many view controllers in one navigation controller. I understand that once there are more than 3 view controllers stacked in a navigation controller, the views are presented "modally"
First of all, what is a "modal" presentation? I looked it up in Swift documentation but I'm having some trouble understanding how it differs from the navigation stack. Second, if there is a problem, is there any way around it?
I'm new to this so help is much appreciated,
Nick
I understand that once there are more than 3 view controllers stacked in a navigation controller, the views are presented "modally"
This is false. You can have as many view controllers in a navigation stack as your app needs, as long as the device has enough memory. View controllers in a navigation stack have a navigation bar (technically, this is part of the navigation controller), a back button and (hopefully) a swipe-right gesture that allow the user to go back "up" the stack. You add a view controller to the stack by calling pushViewController(animated:) and remove it by calling popViewController(animated:) on the navigation controller.
A modal view controller exists outside of the navigation stack. It does not have a navigation bar because it's not in a navigation controller. You are responsible for adding some way to dismiss the modal, such as tapping a close button placed manually in the view controller's view somewhere. You can even add a navigation bar instance manually and put a close button in it. You show a modal by calling present(_:animated:completion:) on the currently-displayed view controller and dismiss it by calling dismiss(_:animated:completion:).
I suspect many have had this case - you present modal view controller, which then present navigation view controller, that has many table view controllers pushing onto the stack. Basically, pushing and presenting controllers. When you get to last you have to dismiss them all, and return to root view controller
Do i have to call for every modal controller dismiss, and for every pushed controller pop, or is there a better way to do this?
I am using iOS5 storyboards if that is relevant somehow.
EDIT:
Thanks for answes but its little more complicated than that - basically i present modal view controller from root controller, than push couple of controllers, then present one more modal view. At that time I want to go to root controller. So just poping view controllers want do it, some of them have to be dissmised
You can return back to the root navigation controller by calling:
[self.navigationController popToRootViewControllerAnimated:YES];
And then release your modal view controller
i'm developing an app for iphone, and i use
[self presentModalViewController:aViewControllerInitializateBefore animated:YES];
Can you tell me what happens to the current viewController when i use this?
The current view controller stays "underneath" the modal view controller and will reappear when you call
- (void)dismissModalViewControllerAnimated:(BOOL)animated
either on the modal view or the parent/presenting view controller (as the parent/presenting view controller's view is no longer visible, it's view may be unloaded when the system requires memory, and reloaded on dismiss).
From this method's documentation:
The parent view controller is responsible for dismissing the modal
view controller it presented using the
presentModalViewController:animated: method. If you call this method
on the modal view controller itself, however, the modal view
controller automatically forwards the message to its parent view
controller.
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. The top-most view is dismissed using its modal transition
style, which may differ from the styles used by other view controllers
lower in the stack.
Also note the change in iOS 5
Prior to iOS 5.0, if a view did not have a parent view controller and
was being presented modally, the view controller that was presenting
it would be returned. This is no longer the case. You can get the
presenting view controller using the presentingViewController
property.
I have a modal that I am calling presentModalViewController to display from a custom menubar. This menubar is overlaying a viewcontroller that is pushed from a tableView cell.
Now... that all being said, I need to find some way to jump the user back to the root of the tableView from the modal screen. Is this possible? I've been fighting with this for the past couple of hours with no results.
If you're starting from a tablview, drilling down to a detail view via a navigation controller, and then presenting a modal view controller on top of that detail view, you'd have two steps to get back to your list/tableview: First you'd dismiss your modal view controller, then you'd pop your detail view off your navigation stack.
That should put you back where you started (at the tablview), if I'm reading this correctly.
You could pass a reference to the navigation controller to the modal view, and then immediately after calling dismissModalViewControllerAnimated, you can use the reference to the navigationController to pop back to the root view controller.
Is my assumption that every controller which is presented with presentModalViewController:animated: need their own UINavigationController stack for their own hierarchy of drill down controllers? Meaning, say I have a top level controller It has its own navigation stack, and an action button which presents another controller via a modal. That modal has its own navigation stack. Is it best to split each modalView with its own Navigation stack?
If you want a modal view to have the forward-and-back behavior provided by a navigation controller, you need to provide a separate navigation controller for it. (If you don't need to push and pop view controllers inside that modal view, then you don't need one, of course.) This can be a bit of a pain, but them's the breaks.