将用户数据保存到结构内部的数组

Saving User Data to Array inside Struct

我想将输入的用户数据/变量正确保存在数组中,该数组位于结构中但无法使其工作。

目前,我有几个结构:

struct Household: Codable {
    let id  = UUID()
    var region: String
    var householdSize: Int = 1
    var receivingBenefits: [String]
    var energyCrisis: Bool
    var utilityProviders: [String]
    var residenceType: String
    var propertyTaxPastDue, homeNeedsRepairs, filedPreviousYearTaxReturn, heatingSystemNeedsRepairs: Bool
    var atRiskOfHomelessness: Bool
    var receivedMaximumBenefit: ReceivedMaximumBenefit
    var personDetails: [PersonDetail]
    var incomes: [Income]
    var assets: [Asset]

    enum CodingKeys: String, CodingKey {
        case region
        case householdSize = "household_size"
        case receivingBenefits = "receiving_benefits"
        case energyCrisis = "energy_crisis"
        case utilityProviders = "utility_providers"
        case residenceType = "residence_type"
        case propertyTaxPastDue = "property_tax_past_due"
        case homeNeedsRepairs = "home_needs_repairs"
        case filedPreviousYearTaxReturn = "filed_previous_year_tax_return"
        case heatingSystemNeedsRepairs = "heating_system_needs_repairs"
        case atRiskOfHomelessness = "at_risk_of_homelessness"
        case receivedMaximumBenefit = "received_maximum_benefit"
        case personDetails = "person_details"
        case incomes, assets
    }
}

struct PersonDetail: Codable, Identifiable {

    let id  = UUID()  // <-- here
    var age: Int = 18
    var maritalStatus: String = ""
    var minimumEmploymentOverExtendedPeriod: Bool
    var workStatus: String = ""
    var pregnant: Bool
    var attendingSchool: Bool = false
    var disabled: Bool

    enum CodingKeys: String, CodingKey {
        case age
        case maritalStatus = "marital_status"
        case minimumEmploymentOverExtendedPeriod = "minimum_employment_over_extended_period"
        case workStatus = "work_status"
        case pregnant
        case attendingSchool = "attending_school"
        case disabled
    }
}

class Base: ObservableObject, Codable {
    @Published var household: Household

    enum CodingKeys: String, CodingKey {
        case household = "household"
    }
}

现在,我可以轻松地将文本字段、切换开关或选择器绑定到 Household 结构下的任何内容,例如下面我认为可以通过 Base() 中的家庭轻松连接 class..

HStack() {
   Image(systemName:"wrench.and.screwdriver.fill")
               .frame(width: 15, height: 15)
  Toggle(isOn: $eligBase.household.homeNeedsRepairs) {
           Text("Need Home Repairs?")
                   .font(.system(size: 15))
              }.tint(.blue)
          }

但是,我无法连接数组`[PersonDetail] 中的任何内容,我将其包含在结构中。

例如,如果我想为“PersonDetail”中的禁用变量连接一个切换开关,我收到一个错误,这是我禁用的切换​​开关:

 Toggle(isOn: $eligBase.household.personDetails.disabled) {
              Text("Disabled")
                        .font(.system(size: 15))
......
}

我收到一条错误消息:

Value of type 'Binding<[PersonDetail]>' has no dynamic member 'disabled' using key path from root type '[PersonDetail]'

关于如何将 Toggles、Textfield、Picker 连接到结构中数组中的变量的任何想法?

您正在尝试将控件绑定到整个 PersonDetail 数组,而不是数组中的单个条目。

例如,如果您总是想使用数组中的第一个 personDetail 实例:

Toggle(isOn: $eligBase.household.personDetails.first!.disabled) {
              Text("Disabled")
                        .font(.system(size: 15))

在实际的解决方案中,您可能希望安全地解包数组中所需的任何 PersonDetail 实例,并干净地处理空数组(因为如果数组为空,我的示例中的强制解包会崩溃)。

您可以为 PersonDetail 的数组使用 List,例如在此示例代码中:

编辑:

struct ContentView: View {
    @StateObject var eligBase = Base()
    
var body: some View {
    List {
        let _ = print("\n---> \(eligBase.household.personDetails.count) \n")
        Section("About You") {
            ForEach($eligBase.household.personDetails) { $person in
                HStack {
                    Text("Age")
                    Spacer()
                    Picker("", selection: $person.age) {
                        ForEach(0...100, id: \.self) {
                            Text("\([=10=])")
                        }
                    }.pickerStyle(.menu)
                }
                HStack {
                    Text("Marital Status")
                    Spacer()
                    Picker("", selection: $person.maritalStatus) {
                        ForEach(0...3, id: \.self) {
                            Text("\([=10=])")
                        }
                    }.pickerStyle(.menu)
                }
            }
        }
    }
    .onAppear {
        eligBase.household = Household(region: "xyz", householdSize: 0, receivingBenefits: [], energyCrisis: false, utilityProviders: [], residenceType: "", propertyTaxPastDue: false, homeNeedsRepairs: false, filedPreviousYearTaxReturn: false, heatingSystemNeedsRepairs: false, atRiskOfHomelessness: false, receivedMaximumBenefit: ReceivedMaximumBenefit(cip: false), personDetails: [PersonDetail(age: 33, maritalStatus: "single", minimumEmploymentOverExtendedPeriod: true, workStatus: "ok", pregnant: false, attendingSchool: false, disabled: false), PersonDetail(age: 44, maritalStatus: "maried", minimumEmploymentOverExtendedPeriod: true, workStatus: "ok", pregnant: false, attendingSchool: false, disabled: true)], incomes: [], assets: [])
    }
}