I am trying to display a list of items in a subview (ListView) inside ContainerView whenever the value of the array of those items is not nil. Every time the array is updated a new ListView should be displayed replacing the previous or be removed if the array is nil. The issue is that ListView seems to be displayed, removed and updated correctly except for the ForEach loop. It uses the same range every time eventhough a new ListView seems to be displayed.
I've created a simple example to demonstrate the issue. This is the ContainerView:
struct ContainerView: View {
@State private var items: [Int]?
private var listView: some View {
items.map { ListView(items: $0) }
}
var body: some View {
VStack {
Button("Display new List") { self.items = self.randomItems() }
listView
}
}
private func randomItems() -> [Int] {...}
}
This is the ListView:
struct ListView: View {
private let randomInt: Int
private let items: [Int]
init(randomInt: Int = Int.random(in: 100 ..< 999), items: [Int]) {
self.randomInt = randomInt
self.items = items
print("init | items: \(items)")
}
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text("\(randomInt)")
ForEach(0 ..< items.count) { index -> Text? in
print("ForEach | index: \(index) items.count: \(self.items.count)")
return self.items.count > index ? Text("\(self.items[index])") : nil
}
}
}
}
When running this and tapping the "Display new List" button several times it will print something like this:
init | items: [0, 1, 2]
ForEach | index: 0 items.count: 3
ForEach | index: 1 items.count: 3
ForEach | index: 2 items.count: 3
init | items: [0, 1, 2, 3, 4, 5, 6, 7, 8]
ForEach | index: 0 items.count: 9
ForEach | index: 1 items.count: 9
ForEach | index: 2 items.count: 9
init | items: [0, 1, 2, 3, 4, 5]
ForEach | index: 0 items.count: 6
ForEach | index: 1 items.count: 6
ForEach | index: 2 items.count: 6
So apparently a new ListView is created and on the device you also see that the correct randomInt is displayed, but for some reason ForEach is using the same range every time no matter how long the new array is.
Why is the range not updating or how can I force it to update?