.modelContainer(for: MyMode.self, isUndoEnabled: true)
This may work for single model containers, but I have a number of models. I don't see how to enable undo for multiple model containers.
.modelContainer(for: MyMode.self, isUndoEnabled: true)
This may work for single model containers, but I have a number of models. I don't see how to enable undo for multiple model containers.
(Don't post while sleepy)
Right in the docs... .modelContainer(for: [MyModel1.self, MyModel2.self], isUndoEnabled: true)
Trying to figure out if this is possible for a sharedModelContainer.
When creating a new empty multiplatform app with SwiftData, this code is automatically generated in the App.swift
:
import SwiftUI
import SwiftData
@main
struct SwiftDataTestApp: App {
var sharedModelContainer: ModelContainer = {
let schema = Schema([
Item.self,
])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(sharedModelContainer)
}
}
Is there a way to set isUndoEnabled
in this scenario? Doesn't look like ModelContainer(for: Schema...)
supports it?
A hackingwithswift article suggests creating a new UndoManager for the shared container. However, this technique doesn't work for me and Undo/Redo commands are greyed out in my test app.
container = try ModelContainer(for: Store.self, Book.self)
container.mainContext.undoManager = UndoManager()
Unlike the Hacking with Swift article, I set my undo manager from the environment and it works. The only catch you can't do in the app context, it has to be on a view level. In any content view, we can access undo manager through the @Environment(\.undoManager) var undoManager
, then when I create my content view I initiate the background task using the .task
modifier, and setting the under manager: modelContext.undoManager = undoManager
. It's probably not a best practice though.
as Borisy did I managed to have it working with by getting the undo manager from the environment on the ContentView
@Environment(\.modelContext) private var modelContext
@Environment(\.undoManager) private var undoManager
Then I use the onAppear modifier
.onAppear() {
modelContext.undoManager = undoManager
}
Then it works as expected.
do {
let container = try ModelContainer(for: schema, configurations: [modelConfiguration])
container.mainContext.undoManager = UndoManager()
return container
} catch {
fatalError("Could not create ModelContainer: (error)")
}
do {
let container = try ModelContainer(for: schema, configurations: [modelConfiguration])
container.mainContext.undoManager = UndoManager()
return container
} catch { fatalError("Could not create ModelContainer: (error)") }
when you need to undo
@Environment(\.modelContext) var modelContext
modelContext.undoManager?.undo()