Skip to content

Instantly share code, notes, and snippets.

@LePips
Last active February 7, 2023 17:01
Show Gist options
  • Save LePips/3640ad0cd9b6e2ceb407e9d0e9e32b5c to your computer and use it in GitHub Desktop.
Save LePips/3640ad0cd9b6e2ceb407e9d0e9e32b5c to your computer and use it in GitHub Desktop.
SwiftUI ViewModifier to keep track of the offset in a ScrollView. Can be expanded for all UIScrollViewDelegate methods and (x, y) offset.
// https://github.com/siteline/SwiftUI-Introspect
import Introspect
struct ScrollViewOffsetModifier: ViewModifier {
@Binding
var scrollViewOffset: CGFloat
private let scrollViewDelegate: ScrollViewDelegate?
init(scrollViewOffset: Binding<CGFloat>) {
self._scrollViewOffset = scrollViewOffset
self.scrollViewDelegate = ScrollViewDelegate()
self.scrollViewDelegate?.parent = self
}
func body(content: Content) -> some View {
content.introspectScrollView { scrollView in
scrollView.delegate = scrollViewDelegate
}
}
private class ScrollViewDelegate: NSObject, UIScrollViewDelegate {
var parent: ScrollViewOffsetModifier?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
parent?.scrollViewOffset = scrollView.contentOffset.y
}
}
}
extension View {
func scrollViewOffset(_ scrollViewOffset: Binding<CGFloat>) -> some View {
self.modifier(ScrollViewOffsetModifier(scrollViewOffset: scrollViewOffset))
}
}
// Example
struct ContentView: View {
@State
private var scrollViewOffset: CGFloat = 0
var body: some View {
ScrollView {
VStack {
Text("Offset: \(scrollViewOffset)")
ForEach(0 ..< 100) { _ in
Text("Hello World!")
}
}
.frame(maxWidth: .infinity)
}
.scrollViewOffset($scrollViewOffset)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment