I'm trying to create a SwiftUI view that includes a List, and I want that list to automatically adjust its height based on its content — without manually calculating something like:
.frame(height: items.count * rowHeight + padding)
My goal is to use the native List (not a VStack or LazyVStack), so that I can preserve the native appearance (e.g. separators, swipe actions, selection, editing). But I want to embed the list in a scrollable parent view, and avoid internal scrolling. In other words:
- Keep native
Liststyling - No internal scroll — only outer
ScrollViewscrolls - Self-sizing height based on content
- No manual height calculation
- No
ForEach-only solution — I'd like to define rows freely if possible
Here's a simplified structure of what I'm doing:
ScrollView {
VStack {
Text("Above the list")
AutoSizingList {
Text("Row 1")
Text("Row 2 — possibly multi-line text that grows")
HStack {
Text("Row 3")
Spacer()
Image(systemName: "chevron.right")
}
}
Text("Below the list")
}
}
And the custom list component I tried (among many versions):
struct AutoSizingList<Content: View>: View {
@ViewBuilder let content: () -> Content
@State private var height: CGFloat = 0
var body: some View {
List {
content()
.background(
GeometryReader { geo in
Color.clear
.preference(key: HeightPreferenceKey.self, value: geo.size.height)
}
)
}
.scrollDisabled(true)
.frame(height: height)
.onPreferenceChange(HeightPreferenceKey.self) { height = $0 }
}
}
private struct HeightPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = max(value, nextValue())
}
}
The result: nothing appears. The List seems to collapse entirely, or SwiftUI fails to lay it out at all. I’ve tried many variations: using ForEach, measuring individual rows, storing their heights in a dictionary, using AnyView, etc.
How can I create a SwiftUI List that:
- renders normally (with default styling);
- auto-sizes to its content height;
- does not scroll internally; and
- works inside a parent
ScrollView?
