Closed rebeloper closed 2 years ago
Thanks, it's a great question.
As you've probably found, having a PStack that contains one or more NStacks within a single view can make state management tricky, as there could be any number of navigation flows to manage. It's easier to break the state out into multiple coordinator views, e.g. a parent coordinator view managing a presentation stack containing child coordinators / views, each of which might themselves manage a navigation stack. If you're using view models, you could have separate view models for the presentation and navigation layers, but still have a single coordinator view. Or, if you have an NStack of which there is always exactly one at the root of your PStack, you could handle both within a single coordinator (though it would behave strangely if you ever presented more than one of your root navigation stacks), e.g.:
struct PNCoordinator: View {
enum Screen {
case root
case hi
}
enum RootScreen {
case home
case hello
}
@State var rootNFlow = NFlow<RootScreen>(root: .home)
@State var mainPFlow = PFlow<Screen>(root: .root)
var body: some View {
PStack($mainPFlow) { screen in
switch screen {
case .root:
NavigationView {
NStack($rootNFlow) { screen in
switch screen {
case .home:
VStack(spacing: 8) {
Text("Home")
Button("Push Hello", action: pushHello)
Button("Present Hi", action: presentHi)
}
case .hello:
VStack(spacing: 8) {
Text("Hello")
Button("Pop", action: pop)
Button("Present Hi", action: presentHi)
}
}
}
}
case .hi:
VStack(spacing: 8) {
Text("Hi")
Button("Dismiss", action: dismiss)
}
}
}
}
func pushHello() {
rootNFlow.push(.hello)
}
func presentHi() {
mainPFlow.present(.root)
}
func pop() {
rootNFlow.pop()
}
func dismiss() {
mainPFlow.dismiss()
}
}
In any case, I'd like to explore ways of making it easier to combine both within a single coordinator view, such as a stack that can be used for both pushing and presenting views.
Thanks for the reply. Had not time to wait for your answer :) so I created my own coordinator that can use both push and present actions: https://github.com/rebeloper/Dot/tree/main/Sources/Dot/LinkedNavigation Let me know what you think. It's heavily influenced by this repo. Thank you.
Nice one! In fact, this issue inspired me to try it out too, and I think my solution is very similar to yours. Allowing the option to embed within a NavigationView
when presenting is the critical part I think. Here's the branch where I've been working on it, though it's not quite shippable yet.
I'll take a closer look at your repo and how you're using it, thanks for sharing!
Support for combined navigation and presentation has now been added in v0.1.0 using the new Router
. 🎉
I did not find a way to have both a push and present navigation type on the same view. Is this possible? Thank you