0

I am trying to create a LazyVGrid based on user selection in another view. As follows, the peoplelist and selectedpersonID are coming from other view.

I understand that I cannot use the "selectedpersons" during initializing of this view. I looked here(Cannot use instance member 'service' within property initializer; property initializers run before 'self' is available) to use onAppear() of the LazyVGrid.

It goes well during compiling and works ok if you select 1 person. Once I selected 2 persons, I got a Fatal error that Index out of range at row.

struct Someview: View {
    
    @ObservedObject var peoplelist : PersonList
    let selectedpersonID : Set<UUID>?

    @State private var days : [String] = Array(repeating: "0", count: selectedpersons.count * 5) //got first error here, during compiling
        
    var body: some View {
        VStack{
            LazyVGrid(columns: columns) {
                Text("")
                ForEach(1..<6) { i in
                    Text("\(i)").bold()
                }
               ForEach(0..< selectedpersons.count , id: \.self) { row in
                    Text(selectedpersons[row].Name)
                    ForEach(0..<5) { col in
                        TextField("", text: $days[row * 5 + col])
                    }
                }
            }
            .onAppear(){
                days = Array(repeating: "0", count: selectedpersons.count * 5)}//no problem during compiling, but will have error when more than 1 person are selected.
            .padding()
        }
    }
    
    var selectedpersons: [Persons] {
        return peoplelist.persons.filter {selectedpersonID!.contains($0.id)}
    }
    
}

It seems to me that this OnAppear() is still slower than the content inside the LazyVGrid? So, the days is not changed quick enough for building the content insider the LazyVGrid? Or did I make an error of the index in the array of days?

z.wang
  • 13
  • 4

1 Answers1

0

It's crashing because ForEach isn't a for loop its a View that needs to be supplied Identifiable data. If you're using indices, id: \self or data[index] then something has gone wrong. There are examples of how to use it correctly in the documentation.

Also onAppear is for performing a side-effect action when the UIView that SwiftUI manages appears, it isn't the correct place to set view data, the data should be already in the correct place when the View struct is init. Making custom Views is a good way to solve this.

malhal
  • 26,330
  • 7
  • 115
  • 133