0
import SwiftUI

struct TestStudentView: View {
    @StateObject var students = Students()
    @State private var name = ""
    @State private var numberOfSubjects = ""
    @State private var subjects = [Subjects](repeating: Subjects(name: "", grade: ""), count: 10)
    
    var body: some View {
        NavigationView {
            Group {
                Form {
                    Section(header: Text("Student details")) {
                        TextField("Name", text: $name)
                        TextField("Number of subjects", text: $numberOfSubjects)
                    }
                    
                    let count = Int(numberOfSubjects) ?? 0
                    Text("Count: \(count)")
                    Section(header: Text("Subject grades")) {
                        if count>0 && count<10 {
                            ForEach(0 ..< count, id: \.self) { number in
                                TextField("Subjects", text: $subjects[number].name)
                                TextField("Grade", text: $subjects[number].grade)
                            }
                        }
                    }
                }
                VStack {
                    ForEach(students.details) { student in
                        Text(student.name)
                        ForEach(student.subjects) { subject in //Does not work as expected
                        //ForEach(student.subjects, id:\.id) { subject in //Does not work as expected
                        //ForEach(student.subjects, id:\.self) { subject in //works fine with this
                            HStack {
                                Text("Subject: \(subject.name)")
                                Text("Grade: \(subject.grade)")
                            }
                        }
                    }
                }
            }
            .navigationTitle("Student grades")
            .navigationBarItems(trailing:
                    Button(action: {
                        let details = Details(name: name, subjects: subjects)
                        students.details.append(details)
                        
                    }, label: {
                    Text("Save")
                })
            )
        }
    }
}

struct TestStudentView_Previews: PreviewProvider {
    static var previews: some View {
        TestStudentView()
    }
}

class Students: ObservableObject {
    @Published var details = [Details]()
}

struct Details: Identifiable {
    let id = UUID()
    var name: String
    var subjects: [Subjects]
}

struct Subjects: Identifiable, Hashable {
    let id = UUID()
    var name: String
    var grade: String
}

当我在正常情况下使用 - "ForEach(student.subjects, id:.id) { subject in" 时,它应该作为 id = UUID 工作,并且不正确的输出如下:

在此处输入图像描述

然后由于课程符合 Identifiable 我试过 - “ForEach(student.subjects) { subject in” 它仍然无法正常工作。但是,当我这样做时 - “ForEach(student.subjects, id:.self) { subject in” 除非我必须让该类符合 hashable 并给我正确的预期输出。显示的正确输出:

在此处输入图像描述

4

1 回答 1

1

您需要使用地图而不是重复。

通过使用 Array.init(repeating:) 将只调用 Subjects 初始化一次,然后将该对象多次插入到数组中。

所以,在这种情况下,所有的 id 都是相同的。

您可以通过打印所有 id 来检查.onAppear() { print(subjects.map({ (sub) in print(sub.id) }))

struct TestStudentView: View {
    @StateObject var students = Students()
    @State private var name = ""
    @State private var numberOfSubjects = ""
    @State private var subjects: [Subjects] = (0...10).map { _ in
        Subjects(name: "", grade: "")
    } //<-- Here
于 2021-02-08T17:06:12.413 回答