Core data 如何在编辑后将CoreData实体中的值显示为状态变量
我目前正在使用SwiftUI中的Core data 如何在编辑后将CoreData实体中的值显示为状态变量,core-data,swiftui,Core Data,Swiftui,我目前正在使用SwiftUI中的CoreData开发一个应用程序 编辑完数据后,我想将CoreData实体中的值显示为状态变量 当我添加一个值作为新日期时,我可以很好地显示该值,但编辑该值后,它不会反映编辑 如果我不使用@State,即使在编辑后,也可以很好地显示该值。但我需要使用as@State值将其绑定到子视图 我怎样才能解决这个问题 (我想在编辑后的某个地方显示collect值,我将其注释为B,与ListView.swift中的likea相同) CDTest.xcdatamodeld
CoreData
开发一个应用程序
编辑完数据后,我想将CoreData
实体中的值显示为状态变量
当我添加一个值作为新日期时,我可以很好地显示该值,但编辑该值后,它不会反映编辑
如果我不使用@State
,即使在编辑后,也可以很好地显示该值。但我需要使用as@State
值将其绑定到子视图
我怎样才能解决这个问题
(我想在编辑后的某个地方显示collect值,我将其注释为B
,与ListView.swift中的likea
相同)
CDTest.xcdatamodeld
CDTestApp.swift
import SwiftUI
@main
struct CDTestApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
ListView()
}
}
import SwiftUI
import CoreData
struct ListView: View {
@StateObject var homeData = HomeViewModel()
@FetchRequest(entity: Task.entity(), sortDescriptors: [NSSortDescriptor(key:"date",
ascending:true)],animation:.spring()) var results:FetchedResults<Task>
@Environment(\.managedObjectContext) var context
var body: some View {
NavigationView{
VStack(spacing:0){
//Empty View...
if results.isEmpty{
Text("NO Data")
}else{
LazyVStack{
ForEach(results){task in
VStack(alignment: .leading, spacing: 5, content: {
Text(task.content ?? "") // A
ListRow(content: task.content ?? "") // B
})
.contextMenu{
Button(action: {
homeData.EditItem(item: task)
}, label: {
Text("Edit")
})
Button(action: {
context.delete(task)
try! context.save()
}, label: {
Text("Delete")
})
}
}
}
.padding()
}
//Add Button...
Button(action: {homeData.isNewDate.toggle()}, label: {
Image(systemName: "plus")
.font(.largeTitle)
.padding()
})
.sheet(isPresented: $homeData.isNewDate, content: {
NewDataView(homeData: homeData)
})
}
}
}
}
import SwiftUI
struct DetailView: View {
@Binding var content:String
var body: some View {
Text(content)
}
}
import SwiftUI
struct NewDataView: View {
@ObservedObject var homeData : HomeViewModel
@Environment(\.managedObjectContext) var context
var body: some View {
VStack{
Text("\(homeData.updateItem == nil ? "Add New" : "Up date")Task")
.font(.title)
TextEditor(text: $homeData.content)
.padding()
//Add Button...
Button(action: {homeData.writeData(context: context)}, label: {
Text(homeData.updateItem == nil ? "Add Now" : "Update")
.font(.title)
.fontWeight(.bold)
})
.padding()
.disabled(homeData.content == "" ? true : false)
.opacity(homeData.content == "" ? 0.5 : 1)
}
}
}
持久控制器
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "CDTest")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
}
}
HomeViewModel.swift
import SwiftUI
import CoreData
class HomeViewModel :ObservableObject{
@Published var content = ""
//for newdata sheet
@Published var isNewDate = false
//storing update Item
@Published var updateItem : Task!
func writeData(context : NSManagedObjectContext){
if updateItem != nil {
updateItem.content = content
try! context.save()
updateItem = nil
isNewDate.toggle()
content = ""
return
}
let newTask = Task(context: context)
newTask.content = content
do{
try context.save()
isNewDate.toggle()
content = ""
}catch{
print(error.localizedDescription)
}
}
func EditItem(item:Task){
updateItem = item
content = item.content!
isNewDate.toggle()
}
}
ListView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
ListView()
}
}
import SwiftUI
import CoreData
struct ListView: View {
@StateObject var homeData = HomeViewModel()
@FetchRequest(entity: Task.entity(), sortDescriptors: [NSSortDescriptor(key:"date",
ascending:true)],animation:.spring()) var results:FetchedResults<Task>
@Environment(\.managedObjectContext) var context
var body: some View {
NavigationView{
VStack(spacing:0){
//Empty View...
if results.isEmpty{
Text("NO Data")
}else{
LazyVStack{
ForEach(results){task in
VStack(alignment: .leading, spacing: 5, content: {
Text(task.content ?? "") // A
ListRow(content: task.content ?? "") // B
})
.contextMenu{
Button(action: {
homeData.EditItem(item: task)
}, label: {
Text("Edit")
})
Button(action: {
context.delete(task)
try! context.save()
}, label: {
Text("Delete")
})
}
}
}
.padding()
}
//Add Button...
Button(action: {homeData.isNewDate.toggle()}, label: {
Image(systemName: "plus")
.font(.largeTitle)
.padding()
})
.sheet(isPresented: $homeData.isNewDate, content: {
NewDataView(homeData: homeData)
})
}
}
}
}
import SwiftUI
struct DetailView: View {
@Binding var content:String
var body: some View {
Text(content)
}
}
import SwiftUI
struct NewDataView: View {
@ObservedObject var homeData : HomeViewModel
@Environment(\.managedObjectContext) var context
var body: some View {
VStack{
Text("\(homeData.updateItem == nil ? "Add New" : "Up date")Task")
.font(.title)
TextEditor(text: $homeData.content)
.padding()
//Add Button...
Button(action: {homeData.writeData(context: context)}, label: {
Text(homeData.updateItem == nil ? "Add Now" : "Update")
.font(.title)
.fontWeight(.bold)
})
.padding()
.disabled(homeData.content == "" ? true : false)
.opacity(homeData.content == "" ? 0.5 : 1)
}
}
}
详细视图.swift
import SwiftUI
struct ContentView: View {
var body: some View {
ListView()
}
}
import SwiftUI
import CoreData
struct ListView: View {
@StateObject var homeData = HomeViewModel()
@FetchRequest(entity: Task.entity(), sortDescriptors: [NSSortDescriptor(key:"date",
ascending:true)],animation:.spring()) var results:FetchedResults<Task>
@Environment(\.managedObjectContext) var context
var body: some View {
NavigationView{
VStack(spacing:0){
//Empty View...
if results.isEmpty{
Text("NO Data")
}else{
LazyVStack{
ForEach(results){task in
VStack(alignment: .leading, spacing: 5, content: {
Text(task.content ?? "") // A
ListRow(content: task.content ?? "") // B
})
.contextMenu{
Button(action: {
homeData.EditItem(item: task)
}, label: {
Text("Edit")
})
Button(action: {
context.delete(task)
try! context.save()
}, label: {
Text("Delete")
})
}
}
}
.padding()
}
//Add Button...
Button(action: {homeData.isNewDate.toggle()}, label: {
Image(systemName: "plus")
.font(.largeTitle)
.padding()
})
.sheet(isPresented: $homeData.isNewDate, content: {
NewDataView(homeData: homeData)
})
}
}
}
}
import SwiftUI
struct DetailView: View {
@Binding var content:String
var body: some View {
Text(content)
}
}
import SwiftUI
struct NewDataView: View {
@ObservedObject var homeData : HomeViewModel
@Environment(\.managedObjectContext) var context
var body: some View {
VStack{
Text("\(homeData.updateItem == nil ? "Add New" : "Up date")Task")
.font(.title)
TextEditor(text: $homeData.content)
.padding()
//Add Button...
Button(action: {homeData.writeData(context: context)}, label: {
Text(homeData.updateItem == nil ? "Add Now" : "Update")
.font(.title)
.fontWeight(.bold)
})
.padding()
.disabled(homeData.content == "" ? true : false)
.opacity(homeData.content == "" ? 0.5 : 1)
}
}
}
NewDataView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
ListView()
}
}
import SwiftUI
import CoreData
struct ListView: View {
@StateObject var homeData = HomeViewModel()
@FetchRequest(entity: Task.entity(), sortDescriptors: [NSSortDescriptor(key:"date",
ascending:true)],animation:.spring()) var results:FetchedResults<Task>
@Environment(\.managedObjectContext) var context
var body: some View {
NavigationView{
VStack(spacing:0){
//Empty View...
if results.isEmpty{
Text("NO Data")
}else{
LazyVStack{
ForEach(results){task in
VStack(alignment: .leading, spacing: 5, content: {
Text(task.content ?? "") // A
ListRow(content: task.content ?? "") // B
})
.contextMenu{
Button(action: {
homeData.EditItem(item: task)
}, label: {
Text("Edit")
})
Button(action: {
context.delete(task)
try! context.save()
}, label: {
Text("Delete")
})
}
}
}
.padding()
}
//Add Button...
Button(action: {homeData.isNewDate.toggle()}, label: {
Image(systemName: "plus")
.font(.largeTitle)
.padding()
})
.sheet(isPresented: $homeData.isNewDate, content: {
NewDataView(homeData: homeData)
})
}
}
}
}
import SwiftUI
struct DetailView: View {
@Binding var content:String
var body: some View {
Text(content)
}
}
import SwiftUI
struct NewDataView: View {
@ObservedObject var homeData : HomeViewModel
@Environment(\.managedObjectContext) var context
var body: some View {
VStack{
Text("\(homeData.updateItem == nil ? "Add New" : "Up date")Task")
.font(.title)
TextEditor(text: $homeData.content)
.padding()
//Add Button...
Button(action: {homeData.writeData(context: context)}, label: {
Text(homeData.updateItem == nil ? "Add Now" : "Update")
.font(.title)
.fontWeight(.bold)
})
.padding()
.disabled(homeData.content == "" ? true : false)
.opacity(homeData.content == "" ? 0.5 : 1)
}
}
}
Xcode:12.0.1版
iOS:14.0
生命周期:SwiftUI应用程序只需将整个任务对象传递到ListRow
,如
VStack(alignment: .leading, spacing: 5, content: {
Text(task.content ?? "") // A
ListRow(task: task) // B // << here !!