Skip to content

Instantly share code, notes, and snippets.

@onevcat
Created October 6, 2022 10:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onevcat/6938ca9cfab1183b7c597e78e23561fe to your computer and use it in GitHub Desktop.
Save onevcat/6938ca9cfab1183b7c597e78e23561fe to your computer and use it in GitHub Desktop.
PartialScroll
import SwiftUI
struct ContentView: View {
@State var offset: CGFloat = 0.0
@State var previousOffset: CGFloat = 0.0
init() {
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = .clear
appearance.shadowColor = .clear
UINavigationBar.appearance().standardAppearance = appearance
}
var body: some View {
NavigationView {
ZStack {
ScrollView(
showsIndicators: false,
offsetChanged: {
previousOffset = offset
offset = $0.y
}
) {
VStack(spacing: 0) {
ForEach(1..<10) { _ in
Rectangle()
.fill(Color.blue)
.frame(height: 100)
Rectangle()
.fill(Color.green)
.frame(height: 100)
}
}.padding(.top, 300 + 104)
}
VStack(spacing: 0) {
Rectangle()
.fill(Color.red)
.frame(height: 300)
Rectangle()
.fill(Color.yellow)
.frame(height: 104)
Spacer()
}
.offset(y: max(-300, offset))
}
.ignoresSafeArea()
.navigationTitle(Text("\(offset)"))
.navigationBarTitleDisplayMode(.inline)
}
}
}
struct ScrollView<Content: View>: View {
let axes: Axis.Set
let showsIndicators: Bool
let offsetChanged: (CGPoint) -> Void
let content: Content
init(
axes: Axis.Set = .vertical,
showsIndicators: Bool = true,
offsetChanged: @escaping (CGPoint) -> Void = { _ in },
@ViewBuilder content: () -> Content
) {
self.axes = axes
self.showsIndicators = showsIndicators
self.offsetChanged = offsetChanged
self.content = content()
}
var body: some View {
SwiftUI.ScrollView(axes, showsIndicators: showsIndicators) {
VStack(spacing: 0) {
GeometryReader { geometry in
Color.clear.preference(
key: ScrollOffsetPreferenceKey.self,
value: geometry.frame(in: .named("scrollView")).origin
)
}.frame(width: 0, height: 0)
content
}
}
.coordinateSpace(name: "scrollView")
.onPreferenceChange(ScrollOffsetPreferenceKey.self, perform: offsetChanged)
}
}
private struct ScrollOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGPoint = .zero
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) {}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
@onevcat
Copy link
Author

onevcat commented Oct 6, 2022

Simulator.Screen.Recording.-.iPhone.14.Pro.-.2022-10-06.at.19.15.21.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment