aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Library/Utility/ObservableScrollView.swift
blob: a6f46cc65ca47fb207135baf1ed4e6008ffdddc5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import SwiftUI

struct ScrollViewOffsetPreferenceKey: PreferenceKey {
  typealias Value = CGFloat
  static var defaultValue = CGFloat.zero
  static func reduce(value: inout Value, nextValue: () -> Value) {
    value += nextValue()
  }
}

struct ObservableScrollView<Content>: View where Content : View {
  @Namespace var scrollSpace
  @Binding var scrollOffset: CGFloat
  let content: () -> Content
  
  init(scrollOffset: Binding<CGFloat>,
       @ViewBuilder content: @escaping () -> Content) {
    _scrollOffset = scrollOffset
    self.content = content
  }
  
  var body: some View {
    ScrollView {
      content()
        .background(GeometryReader { geo in
          let offset = -geo.frame(in: .named(scrollSpace)).minY
          Color.clear
            .preference(key: ScrollViewOffsetPreferenceKey.self,
                        value: offset)
        })
      
    }
    .coordinateSpace(name: scrollSpace)
    .onPreferenceChange(ScrollViewOffsetPreferenceKey.self) { value in
      scrollOffset = value
    }
  }
}