2022-12-20 08:37:07 +00:00
|
|
|
/*! @copyright 2021 Medium */
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
// Source: https://www.fivestars.blog/articles/scrollview-offset/
|
|
|
|
|
|
|
|
public struct ScrollViewOffsetReader<Content: View>: View {
|
|
|
|
let onOffsetChange: (CGFloat) -> Void
|
|
|
|
let content: () -> Content
|
|
|
|
|
|
|
|
public init(
|
|
|
|
onOffsetChange: @escaping (CGFloat) -> Void,
|
|
|
|
@ViewBuilder content: @escaping () -> Content
|
|
|
|
) {
|
|
|
|
self.onOffsetChange = onOffsetChange
|
|
|
|
self.content = content
|
|
|
|
}
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2022-12-20 08:37:07 +00:00
|
|
|
public var body: some View {
|
|
|
|
ScrollView {
|
|
|
|
offsetReader
|
|
|
|
content()
|
|
|
|
.padding(.top, -8)
|
|
|
|
}
|
|
|
|
.coordinateSpace(name: "frameLayer")
|
|
|
|
.onPreferenceChange(OffsetPreferenceKey.self, perform: onOffsetChange)
|
|
|
|
}
|
|
|
|
|
|
|
|
var offsetReader: some View {
|
|
|
|
GeometryReader { proxy in
|
|
|
|
Color.clear
|
|
|
|
.preference(
|
|
|
|
key: OffsetPreferenceKey.self,
|
|
|
|
value: proxy.frame(in: .named("frameLayer")).minY
|
|
|
|
)
|
|
|
|
}
|
|
|
|
.frame(height: 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private struct OffsetPreferenceKey: PreferenceKey {
|
|
|
|
static var defaultValue: CGFloat = .zero
|
2023-01-17 10:36:01 +00:00
|
|
|
static func reduce(value _: inout CGFloat, nextValue _: () -> CGFloat) {}
|
2022-12-20 08:37:07 +00:00
|
|
|
}
|