SwiftUI Nested ForEach should only be used for *constant* data

Viewed 1029

I have created a view with a nested ForEach loop and I am getting the following error in the logs:

> count (2) != its initial count (1). `ForEach(_:content:)` should only
> be used for *constant* data. Instead conform data to `Identifiable` or
> use `ForEach(_:id:content:)` and provide an explicit `id`!

I have made the structs conform to identifiable which doesn't seem to reslove the error.

How can I resolve the error?

import SwiftUI

struct LessonStruct: Identifiable {
    var id: Int
    var name: String
    var questions: [QuestionStruct]
}

struct QuestionStruct: Identifiable {
    var id: Int
    var type: QuestionType
    var description: String
    var questionId: Int
}

class LessonsObject: ObservableObject {
    @Published var Array = [LessonStruct]()
    @Published var selectedLesson: Int?
}

struct CreateLessonList: View {

    @EnvironmentObject var lesson: LessonsObject
    @Binding var showingActionSheet: Bool

    var rowNumber:Int = 0

    var body: some View {


        VStack{


            ForEach(self.lesson.Array) { each in

                VStack(spacing: 0){

                    HStack(){

                        TextField("Lesson \(each.id) - click to change name", text: self.$lesson.Array[each.id-1].name).font(.custom("Proxima Nova Alt Bold", size: 20)).foregroundColor(Color.white).padding(.leading, 10)

                        Spacer()
                        Image("PlusIcon").resizable().frame(width: 20, height: 20).padding(.trailing, 10).onTapGesture {
                            self.lesson.selectedLesson = each.id - 1
                            self.showingActionSheet = true
                        }

                    }.frame( height: 40).background(Color.init("Orange"))


                    if(self.lesson.Array[each.id - 1].questions.count == 0){
                    VStack{
                        Text("Click the '+' icon to add a question.").font(.custom("Proxima Nova Alt Thin", size: 15))
                    }.frame(height: 70)
                    }else{


                        ForEach(self.lesson.Array[each.id - 1].questions.indices){ i in

                            if(self.lesson.Array[each.id - 1].questions[i].type == .Translation){
                                Group{
                                HStack{
                                    Image("TranslationIcon").resizable().frame(width: 50, height:65)
                                    Text(self.lesson.Array[each.id - 1].questions[i].description)
                                    Spacer()
                                }.padding(20)
                                }
                            }

                        }

                    }

                }
            }.background(Color.init("White"))
        }
      }
    }
1 Answers

Use internal ForEach as follows

ForEach(self.lesson.Array[each.id - 1].questions){ question in

    if(question.type == .Translation){
        Group{
        HStack{
            Image("TranslationIcon").resizable().frame(width: 50, height:65)
            Text(question.description)
            Spacer()
        }.padding(20)
        }
    }

}

and review your LessonStruct.id construction logic, cause it looks error prone to refer to [.id - 1].

Related