List sections empty after adding .id()

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.

Answered by RahulRS in 703921022

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())
        }
    }
}

Try wrapping the view inside ForEach with a VStack:

     List {
            ForEach(intervals, id: \.id) { interval in
                Section {
                    VStack { // <-- HERE
                        Text(interval.name)
                     }
                     .id(interval.id) 
                }
            }
        }
Accepted Answer

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())
        }
    }
}
List sections empty after adding .id()
 
 
Q