On an iPad, the leftmost pane (Sidebar) of a SplitNavigationView has a toolbar button that displays a sheet. This sheet can load or delete all SwiftData objects. These objects are listed in the second pane (Content). Hitting the load button creates some new sample data and displays it no problem. However hitting the delete button appears to have no effect and doesn’t trigger a view update.
The model context is in the environment and the list is fed with an @Query. I’ve tried injecting the ModelContext into the SettingsSheet rather than accessing it through the environment but the result is the same. In fact on a relaunch the data is sometimes not even deleted.
I’ve cut the code down to the bare minimum to show the issue and it should just be a copy, paste and run. Am I misunderstanding how the SwiftData operations percolate through the environment? Does the presence of the sheet need handling differently? Any help gratefully received.
import SwiftData
import SwiftUI
@main
struct ProblemTestApp: App {
let container: ModelContainer
var body: some Scene {
WindowGroup {
NavigationSplitView {
SidebarView()
} content: {
ContentView()
} detail: {
DetailTabbedView()
}
.modelContainer(container)
}
}
init() {
let schema = Schema( [ Monkey.self ] )
let configuration = ModelConfiguration("ProblemTestApp", schema: schema)
do {
container = try ModelContainer(for: schema, configurations: configuration)
} catch {
fatalError("Could not configure the SwiftData container.")
}
}
}
// SidebarView
struct SidebarView: View {
@State private var showingSettingsSheet = false
var body: some View {
Text("Sidebar Monkey")
.toolbar {
Button {
showingSettingsSheet.toggle()
} label: {
Label("Show settings", systemImage: "gearshape")
}
}
.sheet(isPresented: $showingSettingsSheet) { /* On dismiss. */ } content: {
SettingsSheet()
}
}
}
// ContentView
struct ContentView: View {
@Query var allMonkeys: [Monkey]
var body: some View {
List {
Text("Monkey count = (allMonkeys.count)")
ForEach(allMonkeys) { monkey in
Text(monkey.name)
}
}
}
}
// DetailTabbedView
struct DetailTabbedView: View {
var body: some View {
Text("Detail Tabbed View (tabs to come)")
}
}
// Monkey model
@Model
final class Monkey: Identifiable {
var id: UUID = UUID()
var name: String = ""
init(name: String) {
self.name = name
}
}
// SettingsSheet
struct SettingsSheet: View {
@Environment(.modelContext) var context
var body: some View {
NavigationStack {
HStack {
Button("Load") {
for _ in 0...9 {
let monkey = Monkey(name: String(Int.random(in: 0...999)))
context.insert(monkey)
}
}
Button("Delete") {
do {
try context.delete(model: Monkey.self)
print("Deleted all the Monkeys")
} catch {
print("Failed to delete all Monkeys.")
}
}
}
.navigationTitle("Monkey Settings")
}
}
}