I am trying to create an interface with a vertical scroll view at the top level, then a horizontal scroll view (using the new paginated scrolling from iOS 17) to display a number of child views that the user can scroll sideways between. So far it's behaving exactly as I want, except that the height of the first of the views in the horizontal scroll view seems to set the height for each of the other views, even if they have a taller content. To be honest, I'm not sure what behavior I imagine this having, but I was wondering if anyone had solved a similar issue or had designed a similar layout another way.
Here is a minimum reproducible example:
import SwiftUI
struct ContentView: View {
@State private var selectedTab: String? = "Tab 1"
var body: some View {
ScrollView(.vertical) {
LazyVStack {
Image(systemName: "photo.fill")
.resizable()
.aspectRatio(contentMode: .fill)
ScrollView(.horizontal) {
LazyHStack(spacing: 0) {
SampleView(.purple, 5)
.id("Tab 1")
.containerRelativeFrame(.horizontal)
SampleView(.red, 12)
.id("Tab 2")
.containerRelativeFrame(.horizontal)
SampleView(.blue, 20)
.id("Tab 3")
.containerRelativeFrame(.horizontal)
}
.scrollTargetLayout()
}
.scrollPosition(id: $selectedTab)
.scrollTargetBehavior(.paging)
}
}
}
@ViewBuilder
func SampleView(_ color: Color, _ size: Int) -> some View {
LazyVGrid(columns: Array(repeating: GridItem(), count: 2), content: {
ForEach(1...size, id: \.self) { _ in
RoundedRectangle(cornerRadius: 15)
.fill(color.gradient)
.frame(height: 150)
}
})
}
}
As you can see from the example, the height of the horizontal scrollview is locked in at the height of the first child view.


