Ios 正在更新数组的成员
我是新手。 我的问题简化了: 我有一个Person结构,由两个字符串组成——名字和姓氏。 包含几个人的初始数组(例如“Bob”“Smith”、“Joe”“Johnson”等) 显示每个成员的列表视图 单击列表中的一行显示一个详细视图,称之为“人员卡”视图,其中显示了姓名 然后我有一个模态视图来编辑这些变量。 当前,模式上的保存按钮仅关闭模式。但是,由于我在模态视图上使用了与“person card”视图上的值的绑定,“person card”视图在模态关闭时用更改的数据进行更新 但是列表视图仍然显示原始值,而不是更新的数据(如我所期望的)。我知道我必须向save函数添加as方法,但我不确定是什么。我知道如何插入和附加到数组,但找不到更新数组方法 仅供参考-我使用的数据模型是作为ObservieObject的类的“存储”实例。我在每个视图中将该变量声明为EnvironmentObject 以下是要求的代码:Ios 正在更新数组的成员,ios,arrays,swift,iphone,swiftui,Ios,Arrays,Swift,Iphone,Swiftui,我是新手。 我的问题简化了: 我有一个Person结构,由两个字符串组成——名字和姓氏。 包含几个人的初始数组(例如“Bob”“Smith”、“Joe”“Johnson”等) 显示每个成员的列表视图 单击列表中的一行显示一个详细视图,称之为“人员卡”视图,其中显示了姓名 然后我有一个模态视图来编辑这些变量。 当前,模式上的保存按钮仅关闭模式。但是,由于我在模态视图上使用了与“person card”视图上的值的绑定,“person card”视图在模态关闭时用更改的数据进行更新 但是列表视图仍然
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。因此,我在下面发布的更新代码中有一条错误消息。