如何使用SwiftUI在详细信息视图上编辑和覆盖CoreData

时间:2020-05-18 06:13:23

标签: ios swiftui swiftui-list

我正在使用一个患者管理系统,需要输入患者的所有相关信息,并在需要时列出,保存和编辑它们。进入详细视图时,我已经设法保存它们,列出它们并显示它们,但是我无法编辑它们并在旧信息上保存新信息。

我已经研究了所有可能的答案,以便能够解决此问题,而我最近发现的问题是正在创建重复的患者文件。

这是我的代码(属性为法语)

PatientList文件:

  struct PatientList: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: PatientInfo.entity(), sortDescriptors: [
        NSSortDescriptor(keyPath: \PatientInfo.nom, ascending: true),
        NSSortDescriptor(keyPath: \PatientInfo.prenom, ascending: true)])
    var patients: FetchedResults<PatientInfo>

    @State private var showingAddScreen = false

    var body: some View {
        NavigationView {
            List {
                ForEach(patients, id: \.self) { patient in
                    NavigationLink(destination: PatientDetail(patients: patient))
                    {
                        VStack{
                            HStack{
                                Text(patient.nom ?? "Inconnu")
                                Text(patient.prenom ?? "Inconnu")
                            }
                        }

                    }
                }
                .onDelete(perform: deletePatients)
            }
            .navigationBarTitle("Patients")
            .navigationBarItems(leading: EditButton(), trailing:
                    Button(action: {
                        self.showingAddScreen.toggle()
                    }) {
                        Image(systemName: "plus")
                }
            )
            .sheet(isPresented: $showingAddScreen) {
                AddNewPatient().environment(\.managedObjectContext, self.moc)
            }

            }


        }
    func deletePatients(at offsets: IndexSet) {
                for offset in offsets {
                    let patient = patients[offset]
                    moc.delete(patient)
                }
                try? moc.save()

        }


struct PatientList_Previews: PreviewProvider {
    static var previews: some View {
        PatientList()
    }
}
}

AddNewPatient文件:

    struct AddNewPatient: View {

    @Environment(\.managedObjectContext) var moc
    @Environment(\.presentationMode) var presentationMode

    @State private var nom = ""
    @State private var prenom = ""
    @State private var ddn = Date()
    @State private var adresse = ""
    @State private var codepostal = ""
    @State private var ville = ""
    @State private var province = ""
    @State private var numerotelephone = "000-000-0000"
    @State private var dernierexamen = Date()



    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Nom", text: $nom)
                    TextField("Prénom", text: $prenom)
                }
                DatePicker("Date de naissance", selection: $ddn, displayedComponents: .date)

                Section {
                    TextField("Adresse", text: $adresse)
                    TextField("Code Postal", text: $codepostal)
                    TextField("Ville", text: $ville)
                    TextField("Province", text: $province)
                }
                Section {
                    TextField("Numéro de téléphone", text: $numerotelephone).keyboardType(.numberPad)
                }
                DatePicker("Dernier examen", selection: $dernierexamen, displayedComponents: .date)
                Section {
                    Button("Enregistrer") {
                        let newPatient = PatientInfo(context: self.moc)
                        newPatient.nom = self.nom
                        newPatient.prenom = self.prenom
                        newPatient.ddn = self.ddn
                        newPatient.adresse = self.adresse
                        newPatient.codepostal = self.codepostal
                        newPatient.ville = self.ville
                        newPatient.province = self.province
                        newPatient.numerotelephone = self.numerotelephone
                        newPatient.dernierexamen = self.dernierexamen

                        try? self.moc.save()
                        self.presentationMode.wrappedValue.dismiss()
                    }
            }
        }
        .navigationBarTitle("Nouveau Patient")
        .navigationBarItems(leading: EditButton())
    }
}

    struct AddNewPatient_Previews: PreviewProvider {
        static var previews: some View {
            AddNewPatient()
        }
    }
    }

PatientDetail文件:

    struct PatientDetail: View {
    @Environment(\.managedObjectContext) var moc
    @Binding var patients: PatientInfo


    @State private var showingEditScreen = false




    var body: some View {
        NavigationView{
            Form{

                Section{
                    Text(self.patients.nom ?? "Nom")
                    Text(self.patients.prenom ?? "Prénom")
                    }

                Section{
                    Text(self.patients.adresse ?? "Adresse")
                    }

                Section{
                    Text(self.patients.codepostal ?? "Code Postal")
                    }
                Section{
                    Text(self.patients.ville ?? "Ville")
                }
                Section{
                    Text(self.patients.province ?? "Province")
                }
                Section{
                    Text(self.patients.numerotelephone ?? "000-000-0000")
                }


            }

        }
        .navigationBarTitle(Text(patients.nom ?? "Inconnu"), displayMode: .inline)
        .navigationBarItems(trailing: Button(action: { self.showingEditScreen.toggle()

        }) {
            Image(systemName: "square.and.pencil")
        }
    )
            .sheet(isPresented: $showingEditScreen) {
                EditPatientView(patients: self.patients).environment(\.managedObjectContext, self.moc)
            }
    }

struct PatientDetail_Previews: PreviewProvider {
    static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    static var previews: some View {
        let patients = PatientInfo(context: moc)
        patients.nom = "Amchou"
        patients.prenom = "Hicham"
        patients.ddn = Date()
        patients.adresse = "7580 Francois Chartrand"
        patients.codepostal = "H7A 3Z9"
        patients.ville = "Laval"
        patients.province = "Québec"
        patients.numerotelephone = "000-000-0000"
        patients.dernierexamen = Date()
        return NavigationView {
            PatientDetail(patients: PatientInfo)
        }
    }
}
}

和EditPatientView文件:

struct EditPatientView: View {

    @Environment(\.presentationMode) var presentationMode
    @Environment(\.managedObjectContext) var moc

    @ObservedObject var patients : PatientInfo


     @State private var nom = ""
     @State private var prenom = ""
     @State private var ddn = Date()
     @State private var adresse = ""
     @State private var codepostal = ""
     @State private var ville = ""
     @State private var province = ""
     @State private var numerotelephone = "000-000-0000"
     @State private var dernierexamen = Date()

    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Nom", text: self.$nom)
                    TextField("Prénom", text: self.$prenom)
                }
                Section {
                DatePicker("Date de naissance", selection: self.$ddn, displayedComponents: .date)
                }
                Section {
                    TextField("Adresse", text: self.$adresse)
                    TextField("Code Postal", text: self.$codepostal)
                    TextField("Ville", text: self.$ville)
                    TextField("Province", text: self.$province)
                }
                Section {
                    TextField("Numéro de téléphone", text: self.$numerotelephone).keyboardType(.numberPad)
                }
                DatePicker("Dernier examen", selection: self.$dernierexamen, displayedComponents: .date)
                Section {
                    Button("Enregistrer") {
                        let newPatient = PatientInfo(context: self.moc)
                        newPatient.nom = self.nom
                        newPatient.prenom = self.prenom
                        newPatient.ddn = self.ddn
                        newPatient.adresse = self.adresse
                        newPatient.codepostal = self.codepostal
                        newPatient.ville = self.ville
                        newPatient.province = self.province
                        newPatient.numerotelephone = self.numerotelephone
                        newPatient.dernierexamen = self.dernierexamen

                        try? self.moc.save()
                        self.presentationMode.wrappedValue.dismiss()
                    }
            }
        }
        .navigationBarTitle("Patient")

    }
}
}


struct EditPatientView_Previews: PreviewProvider {
    static var previews: some View {
        EditPatientView(patients: PatientInfo())
    }
}

(希望这不是太多信息。第一次发布)

1 个答案:

答案 0 :(得分:0)

在EditPatientView中,您可以让患者进行编辑。为什么不编辑它而不是创建新患者呢?喜欢:

struct EditPatientView: View {
    @ObservedObject var patient : PatientInfo
    @Environment(\.managedObjectContext) var managedObjectContext

    var body: some View {
        Form {
            TextField("Name", text: $patient.name ?? "")
        }
        .onDisappear {
            try? self.managedObjectContext.save()
        }
    }
}

问题在于,TextField绑定可能不是可选的,但Core Data字段是可选的。

这个来自https://stackoverflow.com/a/61002589/128083的便捷扩展名可以达到目的:

func ?? <T>(lhs: Binding<T?>, rhs: T) -> Binding<T> {
    Binding(
        get: { lhs.wrappedValue ?? rhs },
        set: { lhs.wrappedValue = $0 }
    )
}

在我的SwiftUIPlayground中也有一个核心数据示例对此进行了演示。