use*_*617 4 ios swift-data swiftui
我正在尝试了解新的 SwiftData 框架。只要我在 SwiftUI 视图中完成所有操作,就很容易让它工作。我试图成为一名优秀的编码员并将数据与 UI 分开,但无法连接到 ModelContainer 并且 ModelContext 是一个类文件。
这是一个可以按原样运行的示例:
模型:
@Model
final public class Thing: Identifiable {
let myID = UUID()
var name: String
var comment: String
init(name: String, comment: String) {
self.name = name
self.comment = comment
}
}//struct
Run Code Online (Sandbox Code Playgroud)
ContentView:更改Button中的代码以创建10条测试记录以使用VM版本。
struct ContentView: View {
@StateObject var contentVM = ContentViewModel()
@Environment(\.modelContext) private var context
@State private var name: String = ""
@State private var comment: String = ""
@State private var selection: Thing?
@Query(sort: \.name) var things: [Thing]
var body: some View {
NavigationStack {
VStack(alignment: .leading) {
Text("Name:")
.padding(.leading, 12)
TextField("name", text: $name)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(EdgeInsets(top: 5, leading: 10, bottom: 0, trailing: 10))
Text("Comment:")
.padding(.leading, 12)
TextField("comment", text: $comment)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(EdgeInsets(top: 5, leading: 10, bottom: 0, trailing: 10))
}//v
.padding()
VStack(spacing: 20) {
Button(action: {
let thing = Thing(name: name, comment: comment)
context.insert(object: thing)
}, label: {
Text("Save")
})
Button(action: {
//contentVM.createThingsForTestVM(count: 10)
createThingsForTest(count: 10)
}, label: {
Text("Create 10 Test Records")
})
}//v buttons
Divider()
List {
ForEach(things) { thing in
Text(thing.name)
}
.onDelete(perform: deleteThings(at:))
}//list
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button {
deleteAllThings()
} label: {
Image(systemName: "trash")
}
}//group
}//toolbar
}//nav stack
}//body
private func deleteThings(at offsets: IndexSet) {
withAnimation {
offsets.map { things[$0] }.forEach(deleteThing)
}
}//delete at offsets
private func deleteThing(_ thing: Thing) {
//Unselect the item before deleting it.
if thing.objectID == selection?.objectID {
selection = nil
}
context.delete(thing)
}//delete things
private func deleteAllThings() {
for t in things {
if t.objectID == selection?.objectID {
selection = nil
}
context.delete(t)
}
}//delete all things
private func createThingsForTest(count: Int) {
for i in 0..<count {
let t = Thing(name: "Name " + String(i), comment: "Comment " + String(i))
context.insert(object: t)
}
do {
try context.save()
} catch {
print(error)
}
}//create things
}//struct content view
Run Code Online (Sandbox Code Playgroud)
ContentViewModel:这确实会创建记录,但不会更新 UI,对我来说这似乎是错误的方法。我尝试在初始化程序中设置 ModelContainer 和 ModelContext,但我根本无法使其工作。
class ContentViewModel: ObservableObject {
init() {}
@MainActor
func createThingsForTestVM(count: Int) {
do {
let container = try ModelContainer(for: Thing.self)
let context = container.mainContext
for i in 0..<count {
let t = Thing(name: "Name " + String(i), comment: "Comment " + String(i))
context.insert(object: t)
}
try context.save()
} catch {
print("Could not create a container \(error.localizedDescription)")
}
}//create things
}//class
Run Code Online (Sandbox Code Playgroud)
任何指导将不胜感激。Xcode 15.0 测试版 (15A5160n)、iOS 17.0
在 SwiftUI 中,View 结构已经与 UI 分离,并且 View 结构层次结构应该是视图数据的主要封装机制。
SwiftUI 区分这些结构并自动为您创建/更新/删除 UI 对象,即它管理实际的视图层或 MVC 中的 V。
因此,您只需删除自定义视图模型对象并按设计使用视图结构和属性包装器即可。
StateObject 适用于当您想要在 State 中使用引用类型时,例如,您正在执行一些与屏幕上的某些内容相关的生命周期异步的操作。现在我们有了 async wait 和任务修饰符,在大多数情况下不再需要它。
| 归档时间: |
|
| 查看次数: |
3090 次 |
| 最近记录: |