Replies: 3 comments 4 replies
-
Im seeing this issue as well 🙂 |
Beta Was this translation helpful? Give feedback.
-
It seems like I can rewrite the destination closure to workaround this, but this seems unsafe...? destination: { destinationStore in
if store.path.last == destinationStore.state {
switch destinationStore {
case .detailItem(let detailStore):
print("Creating a new DetailView")
return DetailView(store: detailStore)
}
}
} And, for whatever it is worth, I can't find an equivalent repro with vanilla SwiftUI. This behaves as expected, only invoking the VanillaDetailView init when navigating to, and not when navigating back/from. struct VanillaContentView: View {
@State var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Form {
Section("Hello world") {
NavigationLink("Detail", value: 1)
}
}
.padding()
.navigationDestination(for: Int.self) { value in
if value == 1 {
VanillaDetailView()
}
}
}
}
}
struct VanillaDetailView: View {
var body: some View {
Text("Detail View")
}
} |
Beta Was this translation helpful? Give feedback.
-
Is this a more faithful vanilla SwiftUI version? If so, it still does not repro the issue (neither with the Dismiss button nor with the back button in the nav bar). @MainActor @Observable
final class ViewModel {
enum Destination {
case detail
}
var path: [Destination] = []
func navigate(to destination: Destination) {
path.append(destination)
}
func popLast() {
guard path.isEmpty == false else { return }
_ = path.popLast()
}
}
struct VanillaContentView: View {
let vm = ViewModel()
var body: some View {
@Bindable var vm = vm
NavigationStack(path: $vm.path) {
Form {
Section("Hello world") {
// NavigationLink("Detail", value: ViewModel.Destination.detail)
Button("Detail") {
vm.navigate(to: .detail)
}
}
}
.padding()
.navigationDestination(for: ViewModel.Destination.self) { destination in
let _ = print("Destination: \(destination)")
switch destination {
case .detail:
VanillaDetailView(vm: vm)
}
}
}
}
}
struct VanillaDetailView: View {
let vm: ViewModel
var body: some View {
VStack {
Text("Detail View")
Button("Dismiss") {
vm.popLast()
}
}
}
}
#Preview {
VanillaContentView()
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi. I'm using TCA 1.14.0 in a visionOS application and I am observing that when navigating back (e.g. dismissing the top-most view on the stack) the
destination
closure of the NavigationStack is invoked with astore.case
value for the current view that is being dismissed, causing the view that is being dismissed to be instantiated again. Is this expected behaviour? I understand that SwiftUI Views get (re)created at various times when the view is recomputed, but I am surprised that the NavigationStack would create a new instance of the view that is in the process of being dismissed.This also repros for iOS. Here's a minimal repro:
The implementation of DetailView is unimportant, but in this case it is simply:
If you watch the console log, or put a breakpoint on
return DetailView(store: detailStore)
you will see that not only is this invoked when navigating to the detail view, but it is invoked again when the user taps on the back button in the nav bar,Beta Was this translation helpful? Give feedback.
All reactions