ios - Navigation between multiple NavigationControllers
Asked Answered
S

2

12

I'm trying to understand a behavior of navigating between ViewControllers with (and without) using a NavigationController and I'm misunderstanding some things while reading articles and docs so I decided to ask them.

Main question is: What happened if we have multiple NavigationControllers in Storyboard and want to go from one to another? (And this can be achieved just using segues as we do between common VCs, am I right?)

As I understand, a NavigationController represents a stack of ViewControllers within which we can pop and push these VCs. So now we change our "location" from VCs of the first NavigationController to VCs from the second one, what happens next? The first stack disappeared and now we work only within the second one? If so, does it means that the VCs stack of the first NavigationController was deleted from memory or not?

Maybe I completely misunderstand something or maybe not:). I will be happy to see your responses and hope to ask you more detail questions about navigation mechanics.

UPDATE

The point is that: Let's say we have one (initial) VC with two buttons that represent two separate parts of the app. Next we click on the first button and go to RootVC of one NC than we go back to our initial VC hit the second button and go to the another NC. What happened with the stack of the first NC when we go back to the initial VC and what is the best way to go "outside" NC to the initial VC?

UPDATE

I'm trying to understand what happens with the memory and which VCs are in the scene at the moment and so on. Maybe it absolutely unimportant if we have some additional VCs in the scene, maybe we do need them to make switching between NCs (or just VCs) faster. So I want just understand how it actually works.

Semiramis answered 22/7, 2015 at 9:5 Comment(0)
T
8

Imagine you have you standard application chain where you push / pop views in initial navigation controller. Then, imagine you have different view that is not part of that chain, like a user profile, which you present as modal view:

enter image description here

Now the top navigation controller is initial so you start from here, while in order to use second one, you would have to access it through UIStoryboard like this (red arrow):

// Get storyboard
let storyboard = UIStoryboard(name: name, bundle: NSBundle.mainBundle())

// Get profile NC
let profileNC = storyboard.instantiateViewControllerWithIdentifier("LoginNC") as! UINavigationController

But if you really want to present profile from one part of the app so it is not modal, you can do it as well (green arrow). The only difference is that now you don't need second navigation controller - so you don't connect push segue to red NC, but to login view controller directly. If you actually try to connect NC - NC and then run it, you will get runtime exception saying that you did it wrong.

Memory

All the VC stay in memory, no matter how you present them. This also holds true for background views when you present something as modal. If you have issues with memory due to long chains, you can implement cleaning / caching logic in your controllers:

func viewWillAppear(animated: Bool) {

    // Call super first
    super.viewWillAppear(animated)

    // Prepare UI
}

func viewWillDisappear(animated: Bool) {

    // Call super first
    super.viewWillAppear(animated)

    // do some memory cleanup, since view will not be visible atm
}

Hope it helps!

Tautomer answered 22/7, 2015 at 13:25 Comment(6)
Thank you for the detailed answer now it makes sense to me! As I understood from [The only difference is that now you don't need second navigation controller - so you don't connect push segue to red NC] and [All the VC stay in memory, no matter how you present them.] there is no need to have multiple NCs at all in the app, we create just one NC and do all the things within it, don't we? Can you give an example when we do need multiple NCs in the app?Semiramis
Yes, if you are only pushing and popping the VCs, one navigation controller is enough. i guess that best example of usage for multiple navigation controllers is when you have left menu in the app that changes your root view (so you go to some list, but also contact form etc. Then you have multiple initial points from which user interacts - and you would have the same amount of NCs as well :)Tautomer
In one of my comments to @Glorfindel I said about one VC (initial) with two buttons that goes to the different app parts (some sort of left panel ;D). In this case after going from Initial VC to the one of NCs we make the last one as a root view, am I right? And what happens with other ones (e.g. when we switch between these NCs)? And also how to go from VC of one NC to particular VC in another NC the right way? (just using show segue?)Semiramis
Too many questions about VCs navigation mechanics but it's driving me crazy for the last couple of weeks ;DSemiramis
Basically, general rules: If you present controller by pushing, you don't need navigation controller (exception throw otherwise). If you present modal view, it is your decision (based on whether you need to push on that modal or not). If you would need to change .topViewController of navigation controller, it is better to use new NC. Other cases are minor but when you will try it few times for yourself, you will understand because it will feel natural what to do and what not. If it requires a lot of work, you are usually doing it wrong :)Tautomer
Thank you! I think I understood the basics of how it works. I'll try to do some test projects to see it in action ;DSemiramis
L
1

What makes sense, is to present a new UINavigationController with its child view controller(s) from an existing one as a modal dialog (this can be done with a modal segue). Each navigation controller has its own stack, and while you're busy in the dialog, the 'master' stack remains intact. When you dismiss the dialog, you will return to the 'master'.

I'm not sure if it is technically possible to push a navigation controller onto an existing one. It makes no sense, though.

Lingerfelt answered 22/7, 2015 at 9:10 Comment(4)
As I understand it adds one NavigationController into the stack of other? I don't need such a behavior (and can't really imagine where it can be used). The point is that: Let's say we have one (initial) VC with to buttons that represent two separate parts of the app. Next we click on the first button and go to RootVC of one NC than we go back to our initial VC hit the second button and go to the another NC. What happened with the stack of the first NC when we go back to the initial VC and what is the best way to go "outside" NC to the initial VC?Semiramis
The behaviour you want reminds me of the UITabBarController, which maintains several child view controllers (which can be navigation controllers). In that case, the tab bar controller maintains the state of each navigation controller.Lingerfelt
In this case app has a stack made from two stacks of these NCs or stacks are separated and only one of them (current) staying in memory and then it will be deallocated while we change it back to the first?Semiramis
I want NC goes out of the app memory if we not in it's stack by the way. And also tabcontroller is not suitable for me, how we can do this without using it? I suppose it should be quite simple, I know how to use segues but I'm trying to understand what happens with the memory and which VCs are in the scene at the moment and so on. Maybe it absolutely unimportant if we have some additional VCs in the scene, maybe we do need them to make switching between NCs (or just VCs) faster. So I want just understand how it actually works.Semiramis

© 2022 - 2024 — McMap. All rights reserved.