Context
I have a pretty basic SwiftUI setup containing of a ListView presenting all Entities and a DetailView presenting just a single of these Entities. The DetailView also has a Delete option.
The problem I have is, that when deleting the Entity, SwiftUI does not navigate back to the ListView, even though the @FetchRequest should update and redraw the View including ChildViews. Instead, it keeps presenting the DetailView but since it deleted the Entity, it only presents the custom-implemented Default ("N/A") Value for its name.
Code
struct ListView: View {
@FetchRequest(sortDescriptors: []) var entities: FetchedResults<Entity>
var body: some View {
NavigationStack {
ForEach(entities) { entity in
RowView(entity: entity)
}
}
}
}
struct RowView: View {
@ObservedObject var entity: Entity
var body: some View {
NavigationLink(destination: DetailView(entity: entity)) {
Text(entity.name)
}
}
}
struct DetailView: View {
@Environment(\.managedObjectContext) private var context
@ObservedObject var entity: Entity
var body: some View {
VStack {
Text(entity.name)
Button(action: { delete() }) { Text("Delete") }
}
}
private func delete() {
context.delete(entity)
do {
try context.save()
} catch let error as NSError {
print(error)
}
}
}
Question
- Why does SwiftUI not navigate back to the
ListViewon Deletion even though the@FetchRequestshould update? How can I achieve this goal?
CodePudding user response:
The FetchRequest does update, but the navigation link isn't dependent upon the parent's fetch request - it's not like a sheet or fullScreenCover where the isPresented or item bound attributes determine the new view's visibility.
The easiest thing to do is to handle the dismissal yourself using the dismiss environment function:
struct DetailView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.managedObjectContext) private var context
// ...
private func delete() {
dismiss()
context.delete(entity)
// ...
}
}
While dismiss() is more commonly seen with modals like sheets and full screen covers, it also works in navigation stacks to pop the current view off the stack.
