ForEach loop or initializer broken

Hey! I am trying to make a game and came across a problem. I simplified the problem by making a new program to test it out, and whenever I try to run it, it says that updating took more than 5 seconds, or nothing shows up at all. If anyone could help me make this work, or suggest a better way to do it, that would be awesome! Thanks! Here's my code

import SwiftUI

struct ContentView: View {
   
  @State var numm = [0, 0]
   
  @State var fill = 1
   
  var body: some View {
    VStack{
      ForEach(1...(20), id: \.self) { box in
        if numm.index(box.self, offsetBy: 0) == 1 {
          Text("\(box.self)")
        }
        else {
          Text("---")
        }
      }
    }
  }
  init() {
    fill = 0
    numm.removeAll()
     
    while fill < 20 {
      numm.append(Int.random(in: 0...1))
      fill += 1
    }
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

I have managed to narrow down the issue to the while loop.

If it were replaced by a for loop, like this:

for _ in 1...20 {
    numm.append(.random(in: 0...1))
    fill += 1
}

it would compile and the preview would work.

Note: the fill variable is now redundant and won't do anything, unless you use it later on somewhere.


After some more debugging, I found that everything in the initialiser has no effect on the two @State variables. You have given them initial values and then tried to change them immediately. Instead, declare them with no value and then set them in the initialiser, like this:

@State private var numm: [Int]
@State private var fill: Int

init() {
    _fill = State(initialValue: 0)

    var initialNumm: [Int] = []

    for _ in 1...20 {
        initialNumm.append(.random(in: 0...1))
    }

    _numm = State(initialValue: initialNumm)
}



Everything else can be kept the same the way you wrote it.

I tested your code, which just does not work.

Why do you need a State fill ?

Minimal change make it work instantly:

struct ContentView: View {
   
  @State var numm = [Int] () // [0, 0]
   
//  @State var fill = 1
   
  var body: some View {
    VStack{
      ForEach(1...(20), id: \.self) { box in
        if numm.index(box.self, offsetBy: 0) == 1 {
          Text("\(box.self)")
        }
        else {
          Text("---")
        }
      }
    }
  }
  init() {
    var fill = 0
    numm.removeAll()
     
    while fill < 20 {
      numm.append(Int.random(in: 0...1))
      fill += 1
    }
  }
}

I get this:

You posted another very similar question. Could you feedback ?

Don't forget to close threads when problem is solved.

ForEach loop or initializer broken
 
 
Q