@@ -8,11 +8,13 @@ public struct ScrollViewReactiveHeader<A, B, C>: View where A: View, B: View, C:
88 public init (
99 @ViewBuilder header: @escaping ( ) -> A ,
1010 @ViewBuilder headerOverlay: @escaping ( ) -> B ,
11- @ViewBuilder body: @escaping ( ) -> C ) {
11+ @ViewBuilder body: @escaping ( ) -> C ,
12+ configuration: ScrollViewConfiguration ) {
1213
1314 self . header = header
1415 self . headerOverlay = headerOverlay
1516 bodyContent = body
17+ self . configuration = configuration
1618 }
1719
1820 // MARK: Public
@@ -40,10 +42,21 @@ public struct ScrollViewReactiveHeader<A, B, C>: View where A: View, B: View, C:
4042 VStack ( content: bodyContent)
4143 . background ( backgroundColor)
4244 }
45+
46+ if configuration. showStatusBar {
47+
48+ Rectangle ( )
49+ . fill ( Color . white)
50+ . opacity ( statusBarOpacity)
51+ . frame ( height: geometry. safeAreaInsets. top)
52+ . edgesIgnoringSafeArea ( . top)
53+ . onAppear {
54+
55+ topSafeArea = geometry. safeAreaInsets. top
56+ }
57+ }
4358 }
4459 . onPreferenceChange ( ScrollViewHeaderKey . self, perform: { preference in
45-
46- print ( " ~ header size: \( preference. rect. height) " )
4760
4861 guard preference. rect != . zero,
4962 headerHeight == . none else { return }
@@ -54,24 +67,10 @@ public struct ScrollViewReactiveHeader<A, B, C>: View where A: View, B: View, C:
5467 . background ( backgroundColor)
5568 . coordinateSpace ( name: " ReactiveHeader " )
5669 . onPreferenceChange ( ScrollViewBodyKey . self, perform: { preference in
57-
58- headerOffset = min ( 0 , preference. rect. minY / 10 )
59-
60- headerScale = max ( 1 , 1 + preference. rect. minY / 500 )
6170
62- print ( preference. rect)
63-
64- guard let headerHeight = headerHeight else { return }
65-
66- let startingY = headerHeight / 2
71+ setStatusBarOpacity ( offset: preference. rect. minY)
6772
68- if abs ( preference. rect. minY) > startingY {
69-
70- headerOpacity = ( 1 - ( abs ( preference. rect. minY) - startingY) / startingY)
71- } else {
72-
73- headerOpacity = 1
74- }
73+ setHeaderOpacity ( preferenceRect: preference. rect)
7574 } )
7675 }
7776
@@ -89,9 +88,48 @@ public struct ScrollViewReactiveHeader<A, B, C>: View where A: View, B: View, C:
8988 private var header : ( ) -> A
9089 private var headerOverlay : ( ) -> B
9190 private var bodyContent : ( ) -> C
91+ private var configuration : ScrollViewConfiguration
9292
9393 @State private var headerHeight : CGFloat ?
9494 @State private var headerOffset : CGFloat = . zero
9595 @State private var headerScale : CGFloat = 1
9696 @State private var headerOpacity : CGFloat = 1
97+
98+ @State private var statusBarOpacity : Double = 0
99+ @State private var topSafeArea : CGFloat = 40
100+
101+ private func setHeaderOpacity( preferenceRect: CGRect ) {
102+
103+ headerOffset = min ( 0 , preferenceRect. minY / 10 )
104+
105+ headerScale = max ( 1 , 1 + preferenceRect. minY / 500 )
106+
107+ guard let headerHeight = headerHeight else { return }
108+
109+ let startingY = headerHeight / 2
110+
111+ if abs ( preferenceRect. minY) > startingY {
112+
113+ headerOpacity = ( 1 - ( abs ( preferenceRect. minY) - startingY) / startingY)
114+ } else {
115+
116+ headerOpacity = 1
117+ }
118+ }
119+
120+ private func setStatusBarOpacity( offset: CGFloat ) {
121+
122+ guard let headerOffset = headerHeight else { return }
123+
124+ let scrollOffset = offset + headerOffset
125+
126+ print ( scrollOffset)
127+
128+ switch scrollOffset {
129+
130+ case 40 ... 60 : statusBarOpacity = Double ( - scrollOffset / 100.0 )
131+ case ... ( 40 ) : statusBarOpacity = 1
132+ default : statusBarOpacity = 0
133+ }
134+ }
97135}
0 commit comments