johnpatrickmorgan / FlowStacks

FlowStacks allows you to hoist SwiftUI navigation and presentation state into a Coordinator
MIT License
854 stars 66 forks source link

Call on navigator on nested view crashes the app #67

Closed sparafinski closed 7 months ago

sparafinski commented 11 months ago

I am trying to reuse a view created in one coordinator and place it in another one. The problem I encounter is that the called view is shown as it should, but all actions called on the navigator (FlowNavigator<>) inside subordinate views cause the application to crashes. What's interesting is that the "first" call on the navigator seems to work as expected - the same cell that is inside the list I'm trying to display opens the dependent view without a problem - only nested navigators seem to have a problem.

App crashes due to fatal error:

No ObservableObject of type FlowNavigator found. A View.environmentObject(_:) for FlowNavigator may be missing as an ancestor of this view.

I noticed that setting the key embedInNavigationView to true fixes this error a bit, however the subordinate views are pushed directly to where the coordinator view is located and not as initially in "proper" but not quite working navigationView.

There you can find demo project with the issue: https://github.com/sparafinski/FlowStacksDemo

And there is a short video presentig the issue: https://github.com/johnpatrickmorgan/FlowStacks/assets/40520109/e9ae83ff-5ccb-40e0-a9c8-8607e17cdf2c

johnpatrickmorgan commented 11 months ago

Thanks @sparafinski for the detailed reproduction. The cause as I understand it is that screens in a NavigationView inherit their environment objects from the NavigationView itself, not the previous screen that pushed them. The error is thrown here because the NavigationView in question is from the parent SecondCoordinator, not the child FirstCoordinator (which does not add its own NavigationView - since embedInNavigationView is false). Since the environment object is added in the child coordinator, not the parent, any pushed screens won't have access to a FlowNavigator<FirstTabViews>.

I'm not sure how best to work around this limitation. You should be fine if you avoid using the FlowNavigator API, instead passing closures to child views. Or you could combine FirstTabViews and SecondTabViews into a single enum used by both coordinators. I appreciate those workarounds might not be ideal though.