Closed Reedyuk closed 2 years ago
Hello. The Counter sample does demonstrate push/pop, including nested back stack.
There is also the TodoApp example, which also demonstrates push/pop.
Both examples have iOS SwiftUI attached.
Here is a code snippet from the counter sample:
var body: some View {
let activeChild = self.routerState.value.activeChild.instance
return VStack(spacing: 8) {
CounterView(self.counterRoot.counter)
Button(action: self.counterRoot.onNextChild, label: { Text("Next Child") })
Button(action: self.counterRoot.onPrevChild, label: { Text("Prev Child") })
.disabled(!activeChild.isBackEnabled)
CounterInnerView(activeChild.inner)
}
}
From what i can see, it's a straight replace, nothing to do with pushing and popping transition.
I was half expecting to see a NavigationView being used in swiftui
@Reedyuk Exactly, the same applicable for any other UI - Jetpack Compose, React, etc. The source of truth for the navigation is Decompose's Router. The Router exposes the navigation state, where there is an active child and a back stack (inactive children). The UI is only concerned about rendering whatever is currently active. So no need to use the NavigationView
, etc. The UI subscribes to the Router
state changes using the Router.state: Value<RouterState>
property -> the Router
pushes a new child into the stack -> the Router
state is updated -> the UI receives the updated state and re-renders.
The tricky part here is animating transitions between screens. Decompose provides APIs for Jetpack Navigation. But there is nothing out-of-the-box for SwiftUI. This was discussed in #21. The explanation of why it's not possible to include animation APIs for SwiftUI into Decompose can be found in the "old" repo - badoo/Decompose/issues/228. So currently, devs have to do something on their own for animations, something similar to what we have for Jetpack Compose.
Using a NavigationView can be desirable, especially when working on a SwiftUI project which targets i.e. both iOS, iPadOS and macOS to achieve visual consistency for each platform. And as far as I know, this is possible while using Decompose for Routing.
@Reedyuk From my understanding, using a NavigationView
just for presentation together with a Decompose router as single source of truth should be possible by implementing a custom binding and passing it as the selection
parameter in this NavigationLink constructor. Only necessary addition compared to this navigation example needed that I can see so far would be adding a tag-Property to Root.Child since NavigationLink
uses tags to identify the currently selected element.
I am currently playing around with Decompose in a personal project and can add a code example if needed once I tested this approach.
@antoniusnaumann Thanks for the useful information. Please don't hesitate do add any code examples, as it may help other devs.
PS: converted this issue to a discussion.
The decompose examples are great but they don't demonstrate a typical navigation stack of pushing and popping.
The counter and master detail examples show a 'replace' navigation but doesn't show a push transition - this is probably the most common navigation pattern used within ios/swiftui
Maybe you could take inspiration of this: https://quickbirdstudios.com/blog/coordinator-pattern-in-swiftui/
Also would be cool to see an example using deeplink navigation, where a user can click an item in the list and this fires off a deeplink to push a view in the navigation.