To keep a section header fixed at the top of a SwiftUI view, you can use the following steps:
Create a parent scrollView
that will contain the section header and the child scrollView
.
Inside the parent scrollView
, add the section header as the first item, followed by the child scrollView
.
Apply a fixed height to the section header, which will determine its size and position.
Add a GeometryReader
to the parent scrollView
to capture its dimensions.
Create a State
variable to store the parent scrollView
offset.
Add a .onPreferenceChange
modifier to the child scrollView
that sends its offset to the parent scrollView
through a PreferenceKey
.
Use the parent scrollView
offset to adjust the position of the section header.
Here's an example implementation:
struct ContentView: View {
@State private var parentScrollViewOffset: CGFloat = 0
var body: some View {
ScrollView {
GeometryReader { geometry in
VStack {
SectionHeader()
.frame(height: 50)
.offset(y: max(-geometry.safeAreaInsets.top, -parentScrollViewOffset))
ChildScrollView()
.background(GeometryReader {
Color.clear.preference(key: OffsetPreferenceKey.self,
value: $0.frame(in: .global).minY)
})
.onPreferenceChange(OffsetPreferenceKey.self) { offset in
parentScrollViewOffset = offset
}
}
}
}
}
}
struct SectionHeader: View {
var body: some View {
Text("Header")
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.background(Color.blue)
}
}
struct ChildScrollView: View {
var body: some View {
ScrollView {
ForEach(1..<100) { index in
Text("Item \(index)")
.frame(height: 50)
.background(Color.gray.opacity(0.2))
}
}
}
}
// Preference key to capture the child scrollView offset
struct OffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
Please start posting anonymously - your entry will be published after you log in or create a new account. This space is reserved only for answers. If you would like to engage in a discussion, please instead post a comment under the question or an answer that you would like to discuss
Asked: 2023-05-22 14:49:11 +0000
Seen: 12 times
Last updated: May 22 '23
How to add a custom button in SwiftUI for iOS13 that enables going back between screens?
How can the update of properties from both ParentViewModel and ChildViewModel in SwiftUI be solved?
Can SwiftUI be utilized to restrict the touch region for a drag gesture?
How can the color of a selected element (Picker) be modified in SwiftUI for WatchOS?
How to make a calendar layout that is horizontal using Swiftui?
What is the process to add a radio button with a check mark on a TableView cell using Swift?
How to limit UITextField input to only accept numerical values?