I have a section for each element in array. I need to use ScrollViewReader so I need to add .id()
to each row. However, when I add id, list rows become empty. It works fine without id modifier. See the image below:
Here's the sample project I have made that demonstrates this problem:
import SwiftUI
import PlaygroundSupport
struct Interval: Identifiable {
var id = UUID()
var index: Int
var name : String {
"Interval \(index)"
}
}
struct ContentView: View {
var intervals: [Interval] = (1...9).map { index in Interval(index: index) }
var body: some View {
List {
ForEach(intervals, id: \.id) { interval in
Section {
Text(interval.name)
//.id(interval.id) // try removing this comment
}
}
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
Some debugging that I have done:
Having only 1 section works, but I need one section for every element.
Section {
ForEach(intervals, id: \.id) { interval in
Text(interval.name)
.id(interval.id)
}
}
Adding each section manually also works, but this can't be done as I have lots of section in my actual project.
Section {
Text(intervals[0].name)
.id(intervals[0].id)
}
Section {
Text(intervals[1].name)
.id(intervals[1].id)
}
Does anyone know how to fix this? Thanks.
Although @snuff4's answer solved the empty cells issue in my real project, scrolling to desired cell/row wasn't working when using ScrollViewReader's scrollTo method.
I have come up with a weird fix that works for me. It is weird because I don't know how and why it works, but it works. If anyone can explain why it works, I'll be very thankful.
The solution is, I created a new ViewModifier named EmbedInSection that just embeds the content in Section.
struct EmbedInSection: ViewModifier {
func body(content: Content) -> some View {
Section {
content
}
}
}
And I used it like:
var body: some View {
List {
ForEach(intervals) { interval in
Text(interval.name)
.id(interval.id)
.modifier(EmbedInSection())
}
}
}