NavigationStack icon indicating copy to clipboard operation
NavigationStack copied to clipboard

Screens are recreated on every change of NavigationStackModel

Open saket opened this issue 4 years ago • 5 comments

I'm not sure if this is an intentional behavior so thought I'd create a discussion. I noticed that my screen Views are getting recreated multiple times during their lifetime. To be more precise, each screen gets created once when it's entering in and twice again when it's exiting out.

From what I understand, this happens because NavigationStackView calls the ViewBuilder closure from its body. Is this expected? I'm creating my View's presenter from inside NavigationModel#showView's closure which is in-turn causing my presenter to get recreated thrice.

Thoughts?

I'm new to SwiftUI so I'm still figuring out the best practices. From what I've seen so far:

  • NavigationLink takes in a destination View as an evaluated property rather than a closure.
  • This library similar to NavigationStack does the same.

saket avatar Aug 16 '21 14:08 saket

Well, it's not really intended that a view gets created multiple times, but necessary because of some SwiftUI limitations. The view to show needs to be pre-rendered before really presenting it otherwise the transition animations might not be visible and because of other bugs in SwiftUI. You can look at the experiments to see SwiftUI's strange behavior and NavigationStackView's code where these experiments are mentioned to explain why the NavigationStackView is written how it is. That's the reason why a view gets created multiple times.

The NavigationLink's destination parameter is a view and not a closure, that's right, but that also causes the destination view to be created even when it's not shown or needed. It will be created automatically only because the source view has a potential destination. That's also not so nice and the reason why NavigationStackView uses a closure because that way the destination view doesn't need to be created in advance when not yet needed.

indieSoftware avatar Aug 18 '21 05:08 indieSoftware

The NavigationLink's destination parameter is a view and not a closure, that's right, but that also causes the destination view to be created even when it's not shown or needed

That's a good point, but one of the advantages of using NavigationStack is that I can programatically create and push Views onto the back-stack, which already puts me in control of when the Views are created. My destination Views are only created when I need to show them, right?

saket avatar Aug 21 '21 20:08 saket

one of the advantages of using NavigationStack is that I can programatically create and push Views onto the back-stack, which already puts me in control of when the Views are created

Not really, views are still defined declaratively in NavigationStack. Only the logic when to trigger is done programmatically / imperatively. So, you don't create a view in code when you want to show it, you still define it in advance, but it is not created until you trigger the transition.

indieSoftware avatar Aug 22 '21 19:08 indieSoftware

same problem,when i push page from a to b or pop view from b to a ,vie a will create more time, so i can't keep view a status, for example,view a have a list,when push or pop,list item will recreate,can you help me?

programmerchan avatar Aug 04 '22 04:08 programmerchan

thanks

programmerchan avatar Aug 04 '22 04:08 programmerchan