0

I start by adding some integers to an array in onAppear for my outermost stack. But when I try to display the contents of the array using ForEach, I get an index out of range error.

struct MyView: View {
    @State private var answers = [Int]()
    var body: some View {
        VStack {
            ForEach(0..<4) { number in 
            Text("\(answers[number])")
            }
        }
        .onAppear {
           for _ in (0..<4) {
               answerArray.append(Int.random(in: 1...10))
           }
        }
3
  • 2
    Do ForEach(answers.indices) instead of ForEach(0..<4) Commented May 25, 2021 at 19:48
  • That stopped it from crashing, but only because it thinks there are no elements in the array. Commented May 25, 2021 at 20:08
  • It's right, there are no elements in the array, at least at first... Commented May 25, 2021 at 20:22

2 Answers 2

1

Never retrieve items by hard-coded indices in a ForEach expression.

Do count the array, the loop is skipped (safely) if the array is empty.

ForEach(0..<answers.count) { number in

Or - still simpler – enumerate the items rather than the indices

ForEach(answers, id: \.self) { answer in 
    Text("\(answer)")
}
Sign up to request clarification or add additional context in comments.

Comments

1

onAppear is called after MyView loads for the first time, and at that moment, answers is still empty. That's why your program crashes at ForEach(0..<4), because answers's doesn't have 4 elements yet.

ForEach(0..<4) { number in 
    Text("\(answers[number])") /// answers is still empty.
}

Instead, you should look over answers.indices, so that answers[number] is guaranteed to exist. Make sure to also provide an id (id: \.self) to satisfy ForEach's Identifiable requirement.

struct MyView: View {
    @State private var answers = [Int]()
    var body: some View {
        VStack {
            ForEach(answers.indices, id: \.self) { number in
                Text("\(answers[number])")
            }
        }
        .onAppear {
            for _ in (0..<4) {
                answers.append(Int.random(in: 1...10)) /// you probably meant `answers.append`, not `answerArray.append`
            }
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.