Reputation: 2983
I have added a List
inside the ScorllView
but it's not showing in canvas after adding inside to ScrollView
here is my code
struct ContentView: View {
var body: some View {
ScrollView {
VStack {
Text("My List")
.font(.largeTitle)
.fontWeight(.bold)
List(0 ..< 5) { item in
Text("Hello World")
}
}
}
}
}
Upvotes: 16
Views: 5047
Reputation: 257493
I assume you expected the following:
var body: some View {
GeometryReader { geometry in
ScrollView {
VStack {
Text("My List")
.font(.largeTitle)
.fontWeight(.bold)
List {
ForEach(0 ..< 50) { item in // 50 for testing
Text("Hello World")
}
}
}
.frame(height: geometry.size.height)
}
}
}
Upvotes: 9
Reputation: 3400
There are many reasons, why you might need a List in a ScrollView. Mine is, that I have a form, where one of the rows is a grid of images, each with a contextMenu. ContextMenu does not work in a List Row with grid content. So, this row can not be in a List. And I have other rows, where I need swipe actions. Which do not work outside of the List. That's why I have to use a List, within a ScrollView. Combining these responses https://stackoverflow.com/a/68789867/1379833, https://stackoverflow.com/a/60758138/1379833 with GeometryReader I got it to work.
import Introspect
@State private var tableViewContentHeight: CGFloat = 0
var body: some View {
GeometryReader { screenGeometryReader in
ScrollView {
... // content of the scrollView
List {
... // content of the list
}
.introspectTableView { tableView in
tableViewContentHeight = tableView.contentSize.height
}
.frame(
width: screenGeometryReader.size.width,
height: tableViewContentHeight
)
}
}
}
Upvotes: 1
Reputation: 119128
That is because List
infer it size from its parent View
. So when you embed it inside something like VStack
that have dynamic height, it can't infer it size correctly.
You have some options here:
List
to match it's content Automatically (Perfect)You can use ForEach
directly instead of using List
, then you have more control over the content size
ForEach(0 ..< 5) { item in
VStack(alignment: .leading) {
Text("Hello World").frame(height: 42)
Divider()
}.padding(.horizontal, 8)
}
You can change all sizes and spacings according to your needs
List
to match it's content manually (Good but not perfect)Give it a static frame like the way you do in UIKit
by setting the .frame()
modifier on the List
:
List(0 ..< 5) { item in
Text("Hello World")
}.frame(height: 224)
You can use GeometryReader
to find the exact size of the parent and apply it to the List
List
(Not good but it works)add .scaledToFill()
modifier to List
Upvotes: 25