Syd*_*olk 7 swift-data swiftui
我正在尝试在基于 SwiftData 的 SwiftUI 项目中使用多个视图。但是,当我在另一个视图中为 SwiftData @Model 对象创建参数时,当我在 #Preview 中创建该对象的示例时,编译器开始抱怨未在 @Model 对象中实现协议。
Xcode 15 测试版 2
我从一个新的 iOS SwiftData 项目开始。我像这样更新了 ContentView:
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
@State private var selection: Item?
var body: some View {
NavigationSplitView {
List(selection: $selection) {
ForEach(items) { item in
Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
} detail: {
DetailView(selection: selection)
}
.navigationSplitViewStyle(.balanced)
}
private func addItem() {
withAnimation {
let newItem = Item(timestamp: Date())
modelContext.insert(newItem)
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(items[index])
}
}
}
}
#Preview {
ContentView()
.modelContainer(for: Item.self, inMemory: true)
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了 DetailView.swift:
import SwiftUI
import SwiftData
struct DetailView: View {
var selection: Item?
var body: some View {
if let item = selection {
Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
} else {
Text("nothing selected")
}
}
}
#Preview {
return DetailView(selection: Item(timestamp: Date()))
.modelContainer(for: Item.self, inMemory: true)
}
Run Code Online (Sandbox Code Playgroud)
Item.swift 与在新项目中生成的方式没有变化:
import Foundation
import SwiftData
@Model
final class Item {
var timestamp: Date
init(timestamp: Date) {
self.timestamp = timestamp
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我在 DetailView 中添加参数时#Preview
,编译器将不会构建项目:
/var/folders/9j/8r6qn35j5jjf0gm3crp6gynw0000gn/T/swift- generated-sources/@_ swiftmacro_12navSplitView4Item5ModelfMc .swift:1:1 类型“Item”不符合协议“PersistentModel”
我需要做什么才能将这些 @Model 对象作为参数传递?
问题是Item
您在#Preview
宏内创建的对象不属于ModelContext
生成错误的实例。
为了解决这个问题,我们首先需要一个单独的ModelContainer
预览,并使用该容器的模型上下文来插入我们在预览中使用的对象,这是一个简单的示例。
#if DEBUG
@MainActor
let previewContainer: ModelContainer = {
do {
let container = try ModelContainer(for: Item.self, ModelConfiguration(inMemory: true))
container.mainContext.insert(Item.preview)
return container
} catch {
fatalError("Failed to create preview container")
}
}()
#endif
Run Code Online (Sandbox Code Playgroud)
其中Item.preview
是定义在的静态属性Item
@Model
final class Item {
// existing code...
static let preview: Item = {
Item(timestamp: .now)
}()
}
Run Code Online (Sandbox Code Playgroud)
然后预览宏改为
#Preview {
DetailView(selection: .preview)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1758 次 |
最近记录: |