Hi guys. I wanted to create a simple grid, but the view does not update after changing the value of "columns".
I guess the @State wrapper doesn't work as expected, even though the value gets changed.
The snippet of code is simplified to be more readable.
The purpose of the snippet: It must change and display a different number of columns depending on the number, however it always displays the default number.
I feel like the answer is easy, but I'd like to comprehend the principle.
struct ContentView: View {
@State private var columns: Int = 4
var body: some View {
VStack{
Text("Number of columns: \(columns)")
HStack{
ForEach(0..<columns){ column in
RoundedRectangle(cornerRadius: 1)
.frame(maxWidth: 1, maxHeight: .infinity)
.padding(10)
}
}
Picker(selection: $columns, label: Text("Columns")) {
ForEach(0..<10){ num in
Text("\(num)").tag(num)
}
}
}
}
}
The error I get:
ForEach<Range, Int, ModifiedContent<ModifiedContent<RoundedRectangle, _FlexFrameLayout>, _PaddingLayout>> count (0) != its initial count (4). ForEach(_:content:) should only be used for constant data. Instead conform data to Identifiable or use ForEach(_:id:content:) and provide an explicit id!
However if I run the code below I get the same error.
struct ContentView: View {
@State private var columns: Int = 4
let myArray: [Int] = Array(0...7)
var body: some View {
VStack{
Text("Number of columns: \(columns)")
HStack{
ForEach(0..<columns){ column in
RoundedRectangle(cornerRadius: 1)
.frame(maxWidth: 1, maxHeight: .infinity)
.padding(10)
}
}
Picker(selection: $columns, label: Text("Columns")) {
ForEach(myArray, id: \.self){ index in
Text("\(myArray[index])").tag(myArray[index])
}
}
}
}
}
Thanks for your time.
bzamayo
(Benjamin Mayo)
2
It's a little strange but that specific ForEach initialiser — that takes a Range of Int — does not participate in the usual dynamic update system. It is only to be used with a constant range (like 0..<4, or 0..<count — where count is a let constant — etc). If you want to use ForEach with data that can change over time, you need to use the ForEach(_:id:) initialiser — so ForEach(0..<columns, id: \.self) is what you are looking for here.
1 Like
Thanks, I should have guessed on my own 