I have a forEach loop inside a view builder function like this:
ForEach(0..<array.count, id: \.id) { index in
array contains a custom model, that conforms to Identifiable and has an id. Problem is when I create another foreach below this one:
ForEach(0..<anotherArray.count, id: \.id) { index in
now, anotherArray also has that custom model type. When running the app it will only show the first foreach, the anotherArray loop is not shown what is inside of it.
I have tried to just discard of the id: .id as this make it work as so:
ForEach(viewModel.array.indices) { index in
and
ForEach(viewModel.anotherArray.indices) { index in
It works but the problem is the warning I'm getting: "Non-constant range: not an integer range"
I cannot find a clean solution for this! It's also worth mentioning that I need the loop to return me the index.
Edit: Forgot to mention this is inside a LazyVStack because I need the pinnedViews argument.
Thanks
CodePudding user response:
The rules are
indices
, explicit integer ranges or primitive arrays like[String]
or[Int]
requireid: \.self
.- An object which does not conform to
Identifiable
but has anid
property requiresid: \.id
(or another hashable property). - An object which does conform to
Identifiable
can omit theid
parameter.
CodePudding user response:
Found out that one can use .id(UUID())
in the view inside each forEach. It will log this warning in the console:
LazyVStackLayout: the ID 0 is used by multiple child views, this will give undefined results!
But this works! Although I must say I don't know if this will give any strange behaviour, for now I'm not seeing any.
CodePudding user response:
The ForEach
View
is not a for loop.
You can't use it with array indices because it'll crash if the array changes because indices are not valid identifiers. I.e. if the item at index 1 moves to 0 it still has the index 1. If you want to use integers then it has to be a static range, e.g.
ForEach(0..<5) { i in
}
Otherwise you have to supply the ForEach with an array of structs that have an identifier, or even better implement the Identifiable
protocol and an id property.
id:\.self
is usually a programmer error because id is supposed to be the keypath to the unique identifier for the data not the data itself.