I want to put a tabView inside a scroll View but when I do so the content of the tabview does not show up even though it is there. How can I fix this bug? The update uses a child size reader as suggested by the comment. Please reference the other so thread for the code for child size reader.
The size of the content in the tabview is dynamic. I know I added 800 for the frame height for each item but this can change.
import SwiftUI
struct SwiftUIView: View {
@State var selectedFilter = 1
var body: some View {
VStack {
Color.blue.frame(height: 85) //header
ScrollView {
LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
Color.green.frame(height: 100) //view body
//red color is tabview header
Section(header: Color.red.frame(height: 30)) {
//view content (THIS DOESNT SHOW)
TabView(selection: $selectedFilter) {
Color.yellow.frame(height: 800).tag(1)
Color.black.frame(height: 800).tag(2)
Color.indigo.frame(height: 800).tag(3)
}
}
}
}
}
}
}
#Preview {
SwiftUIView()
}
Update for Answer
struct SwiftUIView: View {
@State var selectedFilter = 1
var body: some View {
VStack {
Color.blue.frame(height: 85) //header
ScrollView {
LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
Color.green.frame(height: 100) //view body
//red color is tabview header
Section(header: Color.red.frame(height: 30)) {
//view content (THIS DOESNT SHOW)
VStack {
ZStack {
if selectedFilter == 1 {
Color.yellow.frame(height: 5000)
} else if selectedFilter == 2 {
Color.green.frame(height: 100)
}
HStack {
Button("Tab 1") { selectedFilter = 1 }
Button("Tab 2") { selectedFilter = 2 }
}
}
}
}
}
}
}
}
}
You want to place a
TabViewinside aScrollViewin SwiftUI:Instead of using a fixed frame size, which does not accommodate dynamic content, a
GeometryReadercan be used to adapt to the content's size. However, you have mentioned that using aGeometryReaderdirectly did not work as expected.You have updated the code to use a
ChildSizeReader, but it still does not display the content.Consider the design implications of having a
TabViewinside aScrollView. If the content of theTabViewis also scrollable, this can lead to a confusing user experience. It is generally advisable to keep scrolling contexts separate.Yet, as suggested in the comments, creating a custom component that mimics the behavior of
TabViewmight be more effective.That can include a horizontal row of buttons for tab selection and a
ZStackto display the content of the selected tab. That approach offers more control and can be adapted to work within aScrollView.You would get:
As an example:
So the core issue is maintaining the scroll position for each tab independently in a custom tab view implementation.
You might consider a combination of
ScrollViewReaderandGeometryReader.ScrollViewReadercan be used to scroll to a specific position or element, ensuring the correct scroll position is set when switching tabs.ScrollViewReaderto scroll to the top (or the respective stored offset for the new tab).That would be:
Such a code tries to maintain individual scroll positions for each tab: it uses
GeometryReaderto dynamically track and update the scroll position for each tab. AndScrollViewReaderto programmatically control the scroll position when switching tabs.It should help in managing the scroll behavior for each tab independently, preventing the view from crashing when switching between tabs with different content sizes.