【发布时间】:2020-09-30 13:57:23
【问题描述】:
这里是新手。 我的问题简化了:
我有一个由 2 个字符串组成的 Person 结构 - 名字和姓氏。 包含几个人的初始数组(例如“Bob”“Smith”、“Joe”“Johnson”等) 显示每个成员的列表视图。
单击列表中的一行会显示详细视图 - 称之为“个人卡片”视图 - 显示名字和姓氏。
然后我有一个模态视图来编辑这些变量。 目前模态框上的保存按钮仅关闭模态框。但是,因为我在模式视图上使用绑定到“人员卡”视图上的值,所以当模式关闭时,“人员卡”视图会使用更改的数据进行更新。
列表视图仍然显示原始值而不是更新的数据(如我所料)。我知道我必须将 as 方法添加到保存功能,但我不确定是什么。我知道如何插入和追加到数组,但我找不到更新数组方法。
仅供参考 - 我使用的数据模型是 ObservableObject 类的“存储”实例。我在每个视图上将该变量声明为 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()
}
【问题讨论】:
-
嗨 Cubert,您的问题似乎很容易解决,但您能添加一些代码供我们使用吗?或创建一个可重现的演示? stackoverflow.com/help/minimal-reproducible-example
标签: ios arrays swift iphone swiftui