Setting `destination` to nil shows empty screen with "Back"-button, works only once
Closed this issue · 2 comments
In my little app, I am trying to show an edit screen. The model of the screen that hosts to button to drill down to that view has a destination
property. When I navigate to the edit screen, I hide the "Back'-button and show cancellation and confirmation buttons in the toolbar in their respective places.
.navigationDestination(
unwrapping: $model.destination,
case: /VocabularySetDetailViewModel.Destination.edit
) { $editModel in
VocabularyAddEditView(model: editModel)
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button {
model.destination = nil
} label: {
Text("Confirm")
}
}
ToolbarItem(placement: .cancellationAction) {
Button {
model.destination = nil
} label: {
Text("Cancel")
}
}
}
}
For now, I am just setting destination to nil in both cancellation and confirmation button, expecting to get back to the host screen.
What really happens though is that it gets back to an empty screen that just shows the "Back"-button. Tapping on it brings me back to the hosting screen.
When I now drill down to an item again that I want to edit, neither the cancellation nor the confirmation button work. I can see that destination is set to nil when tapping either button by observing it in didSet
, but nothing actually happens in terms of navigation.
I know the above code is really only a small part of the app, but I hope that this might be a common/known thing that someone recognises... Anyways, you can see what's happening in below animated gif.
This is a bug in SwiftUI and something we discussed in episode 217 (at 23:39). If you simply nil
out state driving a navigationDestination
it will not pop the screen off the stack. Typically you can work around by adding @Environment(\.dismiss)
to the child view, but that won't work directly for you since you are doing this directly in the navigationDestination
content closure.
In order to make use of the hack workaround I think you need to wrap VocabularyAddEditView
+toolbars in a little view so that you get access to @Environment(\.dismiss)
for just that child view, and then invoke dismiss()
when you write nil
to the state.
Also I don't think this is an issue with the library, but rather an existing Apple bug. We've filed a bunch of Feedbacks for these bugs, and we encourage you to do the same.
So, I'm going to convert this to a discussion and we can continue the conversation over there.