-
-
Notifications
You must be signed in to change notification settings - Fork 38
Help needed. Combine Portal with programmatic NavigationStack NavigationPath navigation and Zoom transition #23
Copy link
Copy link
Open
Description
Hey! Really like your lib and want to try to do something similar to what Family wallet app does. Basically the idea is to combine Navigation Stack + Zoom transition + Portal shared transition for the image. However, I am running into a couple of issues.
- Since I want to use programmatic navigation with NavigationPath, it's not clear to me what's the cleanest way to trigger isActive portal transition binding?
- I need to define portalTransition per each item in the list. However, the transition call either accepts an ID or an Identifiable binding, both of which doesn't seem like a good fit for my needs.
I feel like I am very close on it, but would love to hear your thoughts on how this could be achieved. Attaching a hacky demo
private struct ContentView2: View {
enum NavDestination: Hashable {
case demo(Int)
}
@State private var path = NavigationPath()
@State private var triggerAnimation = false
@Namespace private var namespace
var body: some View {
NavigationStack(path: $path) {
ScrollView {
VStack {
ForEach(0..<10) { index in
HStack {
Color.red
.frame(width: 50, height: 50)
.clipShape(.circle)
.portal(id: "demo\(index)", .source)
Text("Some text title")
}
.frame(maxWidth: .infinity, alignment: .leading)
.matchedTransitionSource(id: "demo\(index)", in: namespace)
.onTapGesture {
triggerAnimation.toggle()
path.append(NavDestination.demo(index))
}
}
}
}
.navigationDestination(for: NavDestination.self) { destination in
switch destination {
case .demo(let index):
ScrollView {
VStack(alignment: .leading) {
HStack {
Color.red
.frame(width: 50, height: 50)
.clipShape(.circle)
.portal(id: "demo\(index)", .destination)
.onDisappear {
triggerAnimation.toggle()
}
Text("Some text bla bla bla bla")
}
}
}
.navigationTransition(.zoom(sourceID: "demo\(index)", in: namespace))
}
}
// How to trigger isActive binding by only relying on current navigation path?
.portalTransition(id: "demo0", isActive: $triggerAnimation) {
Color.red
.clipShape(.circle)
}
.portalTransition(id: "demo9", isActive: $triggerAnimation) {
Color.red
.clipShape(.circle)
}
// How to set the portalTransition for multiple IDs but without the identifiable?
}
.portalContainer()
}
}
The example of the UI I want to implement. Obviously it has much more than that, but Portal + Zoom gets pretty close
ScreenRecording_07-29-2025.23-49-24_1.MP4
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels