Reputation: 155
I'm trying to create a scroll view with my custom view, but when I add scroll to view it's not working as expected, without scroll view working fine.
struct ContentView: View {
var body: some View {
ScrollView(.vertical) {
VStack {
ForEach (0..<2) { _ in
ListItem()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// But the below code is working fine.
struct ContentView: View {
var body: some View {
VStack {
ForEach (0..<2) { _ in
ListItem()
}
}
}
}
// List Item
struct ListItem: View {
var body: some View {
VStack {
HStack {
Image("steve")
.resizable()
.clipShape(Circle())
.aspectRatio(contentMode: .fit)
.frame(maxWidth:44, maxHeight: 44)
VStack {
Text("Steve Jobs")
.font(.headline)
.frame(maxWidth: .infinity, alignment: .leading)
Text("1 hour ago")
.font(.footnote)
.frame(maxWidth: .infinity, alignment: .leading)
}
Spacer()
}
ZStack(alignment:.top) {
GeometryReader { geometry in
VStack {
ZStack {
Image("poster_1")
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(8)
.shadow(color: Color.black.opacity(0.12),
radius: 4, x: 1, y: 1)
.frame(width: geometry.size.width - 64,
height: geometry.size.height * 0.35)
.padding([.horizontal], 32)
.clipped()
ZStack {
Rectangle()
.fill(Color.black.opacity(0.75))
.frame(maxWidth:84 , maxHeight: 84)
.cornerRadius(12)
Image(systemName: "play.fill")
.font(.system(size: 44, weight: .bold))
.foregroundColor(.white)
}
}
VStack {
Text("Game of Thrones")
.accentColor(Color.gray.opacity(0.25))
.font(Font.subheadline.weight(.bold))
.padding([.horizontal], 32)
.padding([.bottom], 2)
.frame(maxWidth: .infinity,
alignment: .leading)
VStack {
Text("Game of Thrones is an American fantasy drama television series created by David Benioff and D. B. Weiss for HBO. ")
.accentColor(Color.gray.opacity(0.25))
.font(.footnote)
.frame(maxWidth: .infinity,
alignment: .leading)
.padding([.horizontal], 32)
Text("Show more...")
.accentColor(Color.gray.opacity(0.01))
.font(Font.footnote.weight(.bold))
.frame(maxWidth: .infinity,
alignment: .trailing)
.padding([.trailing], 32).onTapGesture {
print("okay")
}
}
}
}
}
}
}
}
}
ListItem contains multiple views which creates publisher info and movie information as shown below image.
Scrollview is scrolling but images are not shown in view as first image.
Upvotes: 2
Views: 7174
Reputation: 9755
It is the geometry reader that you have in ListItem
. Because neither a GeometryReader nor a Scrollview have their own size. Since neither know what size to render, they collapse. This is what you are seeing in your view. See this answer. The solution is to put the GeometryReader
into ContentView
outside the Scrollview
and send the GeometryProxy
that you called geometry
into ListItem
something like this:
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
ScrollView(.vertical) {
VStack {
ForEach (0..<2) { _ in
ListItem(geometry: geometry)
}
}
} // Scrollview
} // GeometryReader
}
}
struct ListItem: View {
let geometry: GeometryProxy
var body: some View {
...
}
This seems to fix it in Preview, though you may have to change your multipliers in the .frame()
that uses geometry
to size it how you want.
Upvotes: 3