I have a SwiftUI view that is being passed a binding from a parent view. I would like to preview the subview, but can't. I tried .constant and a @Model object directly. Both ways crash the preview.
Any idea on how I can get this to work properly?
@Model
class FamilyMember: Identifiable {
@Attribute(.unique) var id: String { name }
var name = ""
init(name: String = "") {
self.name = name
}
}
struct MemberView: View {
@Bindable var member: FamilyMember
var body: some View {
Text(member.name)
}
}
#Preview {
MemberView(member: FamilyMember(name: "Family member"))
}
#Preview {
MemberView(member: .constant(FamilyMember(name: "Family member")))
}
I think this is a bug but with this wrapper you can work around it.
struct SwiftDataPreviewWrapper<Content: View>: View {
@ViewBuilder var view: Content
let modelContainer: ModelContainer
init<S>(of type: S.Type, view: () -> Content) where S : PersistentModel {
do {
modelContainer = try ModelContainer(for: type, configurations: .init(isStoredInMemoryOnly: true))
} catch {
fatalError("Could not initialize ModelContainer")
}
self.view = view()
}
var body: some View {
view
.modelContainer(modelContainer)
}
}
Then you can use it with any @Model
like this
#Preview {
SwiftDataPreviewWrapper(of: FamilyMember.self){
MemberView(member: FamilyMember(name: "Family member"))
}
}
The premise behind the wrapper working is that the model container is created and set before the initialization of the object.
Using the modelContainer ViewModifier causes the same crash that says a container isn’t available.