Core data 如何在编辑后将CoreData实体中的值显示为状态变量

Core data 如何在编辑后将CoreData实体中的值显示为状态变量,core-data,swiftui,Core Data,Swiftui,我目前正在使用SwiftUI中的CoreData开发一个应用程序 编辑完数据后,我想将CoreData实体中的值显示为状态变量 当我添加一个值作为新日期时,我可以很好地显示该值,但编辑该值后,它不会反映编辑 如果我不使用@State,即使在编辑后,也可以很好地显示该值。但我需要使用as@State值将其绑定到子视图 我怎样才能解决这个问题 (我想在编辑后的某个地方显示collect值,我将其注释为B,与ListView.swift中的likea相同) CDTest.xcdatamodeld

我目前正在使用SwiftUI中的
CoreData
开发一个应用程序

编辑完数据后,我想将
CoreData
实体中的值显示为状态变量

当我添加一个值作为新日期时,我可以很好地显示该值,但编辑该值后,它不会反映编辑

如果我不使用
@State
,即使在编辑后,也可以很好地显示该值。但我需要使用as
@State
值将其绑定到子视图

我怎样才能解决这个问题

(我想在编辑后的某个地方显示collect值,我将其注释为
B
,与
ListView.swift中的like
a
相同)


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 !!