Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 正在更新数组的成员_Ios_Arrays_Swift_Iphone_Swiftui - Fatal编程技术网

Ios 正在更新数组的成员

Ios 正在更新数组的成员,ios,arrays,swift,iphone,swiftui,Ios,Arrays,Swift,Iphone,Swiftui,我是新手。 我的问题简化了: 我有一个Person结构,由两个字符串组成——名字和姓氏。 包含几个人的初始数组(例如“Bob”“Smith”、“Joe”“Johnson”等) 显示每个成员的列表视图 单击列表中的一行显示一个详细视图,称之为“人员卡”视图,其中显示了姓名 然后我有一个模态视图来编辑这些变量。 当前,模式上的保存按钮仅关闭模式。但是,由于我在模态视图上使用了与“person card”视图上的值的绑定,“person card”视图在模态关闭时用更改的数据进行更新 但是列表视图仍然

我是新手。 我的问题简化了:

我有一个Person结构,由两个字符串组成——名字和姓氏。 包含几个人的初始数组(例如“Bob”“Smith”、“Joe”“Johnson”等) 显示每个成员的列表视图

单击列表中的一行显示一个详细视图,称之为“人员卡”视图,其中显示了姓名

然后我有一个模态视图来编辑这些变量。 当前,模式上的保存按钮仅关闭模式。但是,由于我在模态视图上使用了与“person card”视图上的值的绑定,“person card”视图在模态关闭时用更改的数据进行更新

但是列表视图仍然显示原始值,而不是更新的数据(如我所期望的)。我知道我必须向save函数添加as方法,但我不确定是什么。我知道如何插入和附加到数组,但找不到更新数组方法

仅供参考-我使用的数据模型是作为ObservieObject的类的“存储”实例。我在每个视图中将该变量声明为EnvironmentObject

以下是要求的代码:

struct PatientData: Identifiable
{
    let id = UUID()

    var patientName: String
    var age: String

}



let patientDataArray: [PatientData] = 

[  
    PatientData(patientName: "Charles Brown", age: "68"),
    PatientData(patientName: "Jim Morrison", age: "36"),
]



final class PatientDataController: ObservableObject
{
@Published var patients = patientDataArray
{



struct PatientList: View
{
    @EnvironmentObject var patientDataController: PatientDataController
    @State private var showModalSheet = false

    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach(patientDataController.patients)
                { patientData in    NavigationLink(destination: PatientInfoCard(patientData: patientData))
                { PatientListCell(patientData: patientData) }
                }
                .onMove(perform: move)
                .onDelete(perform: delete)

                .navigationBarTitle(Text("Patient List"))
            }



struct PatientInfoCard: View
{
    @EnvironmentObject var patientDataController: PatientDataController

    @State var patientData: PatientData
    @State private var showModalSheet = false

    var body: some View
    {
        VStack(alignment: .leading, spacing: 8)
        {  // Change to patientDataArray???
            Text(patientData.patientName)
                .font(.largeTitle)
            BasicInfo(patientData: patientData)
            Spacer()
                .frame(minWidth: 0, maxWidth: .infinity)
        }
        .padding()

        // Can't push Edit button more than once
        .navigationBarItems(trailing: Button(action:
            {self.showModalSheet = true})
                {Text("Edit")})
            .sheet(isPresented: $showModalSheet)
        {
            EditPatientModal(patientData: self.$patientData, showModalSheet: self.$showModalSheet)
                .environmentObject(self.patientDataController)

        }
    }
}



struct EditPatientModal: View
{
    @Environment(\.presentationMode) var presentationMode
    @EnvironmentObject var patientDataController: PatientDataController
    @Binding var patientData: PatientData
    @Binding var showModalSheet: Bool

    var body: some View
    {
        NavigationView
        {
            VStack(alignment: .leading)
            {
                Text("Name")
                    .font(.headline)
                TextField("enter name", text: $patientData.patientName)


                Text("Age")
                    .font(.headline)
                TextField("enter age", text: $patientData.age)

            }
            .navigationBarTitle(Text("Edit Patient"), displayMode: .inline)
            .navigationBarItems(
                leading: Button("Cancel")
                    { self.cancel() },
                trailing: Button("Save")
                    { self.save() } )
        }
    }

    private func save()
    {

        self.presentationMode.wrappedValue.dismiss()
    }
这是我的更新代码:

class PatientData: ObservableObject, Identifiable
{
    let id = UUID()

    @Published var patientName = ""
    @Published var age = ""

    init(patientName: String, age: String)
    {
        self.patientName = patientName
        self.age = age

    }
}



let patientDataArray: [PatientData] =
[
    PatientData(patientName: "Charles Brown", age: "68"),
    PatientData(patientName: "Jim Morrison", age: "36")    
]



final class PatientDataController: ObservableObject
{
    @Published var patients = patientDataArray
}



struct PatientList: View
{
    @EnvironmentObject var patientDataController: PatientDataController
    @EnvironmentObject var patientData: PatientData
    @State private var showModalSheet = false

    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach(self.patientDataController.patients.indices)
                { idx in
                NavigationLink(destination: PatientInfoCard(patientData: self.$patientDataController.patients[idx]))

 /*Cannot convert value of type 'Binding<PatientData>' to expected argument type 'PatientData'*/ <-- My one error message; in NavigationLink

                { PatientListCell(patientData: self.$patientDataController.patients[idx]) }
                }
                .onMove(perform: move)
                .onDelete(perform: delete)

                .navigationBarTitle(Text("Patient List"))
            }
        .navigationBarItems(leading: EditButton())



struct PatientInfoCard: View
{
    @EnvironmentObject var patientDataController: PatientDataController

    @Binding var patientData: PatientData
    @State private var showModalSheet = false

    var body: some View
    {
        VStack(alignment: .leading, spacing: 8)
        {  
            Text(patientData.patientName)
                .font(.largeTitle)
            BasicInfo(patientData: patientData)
            Spacer()
                .frame(minWidth: 0, maxWidth: .infinity)
        }
        .padding()
        .navigationBarItems(trailing: Button(action:
            {self.showModalSheet = true})
                {Text("Edit")})
            .sheet(isPresented: $showModalSheet)
        {
            EditPatientModal(patientData: self.$patientData, showModalSheet: self.$showModalSheet)
                .environmentObject(self.patientDataController)

        }
    }
}


struct BasicInfo: View
{
    @EnvironmentObject var patientDataController: PatientDataController

    @State var patientData: PatientData

    var patientDataIndex: Int
    {
        patientDataController.patients.firstIndex(where: { $0.id == patientData.id })!
    }

    var body: some View
    {
        VStack(alignment: .leading, spacing: 8)
        {

            Text("Age:")
                .font(.headline)
            Text(patientData.age)
                .font(.subheadline)
                .foregroundColor(.secondary)

        }
    }
}



struct EditPatientModal: View
{
    @Environment(\.presentationMode) var presentationMode
    @EnvironmentObject var patientDataController: PatientDataController

    @Binding var patientData: PatientData
    @Binding var showModalSheet: Bool

    var body: some View
    {
        NavigationView
        {
            VStack(alignment: .leading)
            {
                Text("Name")
                    .font(.headline)
                TextField("enter name", text: $patientData.patientName)


                Text("Age")
                    .font(.headline)
                TextField("enter age", text: $patientData.age)

            }
            .navigationBarTitle(Text("Edit Patient"), displayMode: .inline)
            .navigationBarItems(
                leading: Button("Cancel")
                    { self.cancel() },
                trailing: Button("Save")
                    { self.save() } )
        }
    }

    private func save()
    {

        self.presentationMode.wrappedValue.dismiss()
    }
class PatientData:可观察对象,可识别
{
设id=UUID()
@已发布的var patientName=“”
@已发布变量age=“”
初始化(患者名称:字符串,年龄:字符串)
{
self.patientName=patientName
self.age=年龄
}
}
让PatientData数组:[PatientData]=
[
患者数据(患者姓名:“查尔斯·布朗”,年龄:“68”),
患者数据(患者姓名:“吉姆·莫里森”,年龄:“36”)
]
最终类PatientDataController:ObservieObject
{
@已发布的var患者=patientDataArray
}
结构耐心列表:视图
{
@环境对象变量patientDataController:patientDataController
@环境对象变量patientData:patientData
@状态私有变量showModalSheet=false
var body:一些观点
{
导航视图
{
列表
{
ForEach(self.patientDataController.patients.index)
{idx-in
导航链接(目的地:PatientFoCard(patientData:self.$patientDataController.patients[idx]))

/*无法将“Binding”类型的值转换为预期的参数类型“PatientData”*/代码中缺少2项内容

您的结构必须是
observegeobject
,否则对其进行的任何更改都不会生效,为了使其成为
observegeobject
,它必须是一个类,因此第一次更改:

class PatientData: ObservableObject, Identifiable
{
    let id = UUID()
    @Published var patientName: String
    @Published var age: String

    init(patientName: String, age: String) {
        self.patientName = patientName
        self.age = age
    }
}
我知道您有一个正在发布的
environmentObject
,但它只发布对数组的更改,这意味着添加或删除项目,而不是单个
patientData
对象

第二件需要更改的事情是在您的
forEach循环中
您需要将
患者
作为
绑定进行传递,为了做到这一点,您必须循环索引,然后通过
绑定访问数据

NavigationView
        {
            if(self.patientDataController.patients.count > 0) {
                    List {
                        ForEach(self.patientDataController.patients.enumerated().map({$0}), id:\.element.id) { idx, patient in
                            NavigationLink(destination: PatientInfoCard(patientData: self.$patientDataController.patients[idx])) {
                                Text(patient.patientName)
                            }
                        }
                    }
                    .navigationBarItems(leading: EditButton())
                } else {
                    Text("List is empty")
                }
        }

如果这不起作用,请告诉我们您的代码中缺少了两项内容

您的结构必须是
observegeobject
,否则对其进行的任何更改都不会生效,为了使其成为
observegeobject
,它必须是一个类,因此第一次更改:

class PatientData: ObservableObject, Identifiable
{
    let id = UUID()
    @Published var patientName: String
    @Published var age: String

    init(patientName: String, age: String) {
        self.patientName = patientName
        self.age = age
    }
}
我知道您有一个正在发布的
environmentObject
,但它只发布对数组的更改,这意味着添加或删除项目,而不是单个
patientData
对象

第二件需要更改的事情是在您的
forEach循环中
您需要将
患者
作为
绑定进行传递,为了做到这一点,您必须循环索引,然后通过
绑定访问数据

NavigationView
        {
            if(self.patientDataController.patients.count > 0) {
                    List {
                        ForEach(self.patientDataController.patients.enumerated().map({$0}), id:\.element.id) { idx, patient in
                            NavigationLink(destination: PatientInfoCard(patientData: self.$patientDataController.patients[idx])) {
                                Text(patient.patientName)
                            }
                        }
                    }
                    .navigationBarItems(leading: EditButton())
                } else {
                    Text("List is empty")
                }
        }

让我们知道如果这不起作用

Hi Cubert,你的问题似乎很容易解决,但是你能为我们添加一些代码吗?或者创建一个可复制的演示吗?Hi Cubert,你的问题似乎很容易解决,但是你能为我们添加一些代码吗?或者创建一个可复制的演示吗?谢谢。我注意到我没有为e“PatientInfoCard”结构(或者我在问题的简要描述中称之为“PersonCard”)。我目前正在工作,所以当我回家时,我将添加该代码并进行2项建议的更改。我不知道声明变量的结构也必须是一个可观察对象(因此也是一个类)。我认为只有这些变量的数组是必须的。一点也不担心,我注意到了这一点,但我不认为这会有什么不同,但如果我的建议不起作用,那么更新代码,我应该能够提供帮助。注:我添加了“PatientInfoCard”我的代码中的结构-不确定它是否重要。明白了,请确保进行我建议的更改,如果它不起作用,我将查看您的PatientFocard。下面我发布的更新代码中有一条错误消息。谢谢。我注意到我没有为“PatientFocard”结构(或“PersonCard”)添加代码正如我在对问题的简要描述中所说的那样)。我目前正在工作,所以当我回家后,我会添加代码并进行2项建议的更改。我不知道声明变量的结构也必须是一个ObserveObject(因此也是一个类)。我认为只有这些变量的数组是必须的。一点也不担心,我注意到了这一点,但我不认为这会有什么不同,但如果我的建议不起作用,那么更新代码,我应该能够提供帮助。注:我添加了“PatientInfoCard”我的代码中的结构-不确定它是否重要。明白了,请确保进行我建议的更改,如果它不起作用,我将查看您的PatientFocard。因此,我在下面发布的更新代码中有一条错误消息。