-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
TestFlexibleStickyHeader.swift
58 lines (54 loc) · 1.68 KB
/
TestFlexibleStickyHeader.swift
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// 🔥BOYCOTT on russia - terrorist must be punished!
// «Русский военный корабль, иди на хуй!» (c) Ukrainian Frontier Guard
//
// ATTENTION: This is a demo - use it as you wish. Reference is appriciated.
// If you want to thank - buy me coffee: https://secure.wayforpay.com/donate/asperi
import SwiftUI
struct TestFlexibleStickyHeader: View {
@State var imageHeight: CGFloat = 0
let headerHeight: CGFloat = 200
var body: some View {
ScrollView {
// just remove .sectionHeaders to make it non-sticky
LazyVStack(spacing: 8, pinnedViews: [.sectionHeaders]) {
Section {
// >> any content
ForEach(0...100) {
Text("Item \($0)")
.frame(maxWidth: .infinity, minHeight: 60)
.background(RoundedRectangle(cornerRadius: 12).fill($0%2 == 0 ? .blue : .yellow))
.padding(.horizontal)
}
// << content end
} header: {
// here is only caculable part
GeometryReader {
// detect current position of header bottom edge
Color.clear.preference(key: ViewOffsetKey.self,
value: $0.frame(in: .named("area")).maxY)
}
.frame(height: headerHeight)
.onPreferenceChange(ViewOffsetKey.self) {
// prevent image illegal if header is not pinned
imageHeight = $0 < 0 ? 0.001 : $0
}
}
}
}
.coordinateSpace(name: "area")
.overlay(
// >> any header
Image("picture").resizable().scaledToFill()
// << header end
.frame(height: imageHeight)
.clipped()
.allowsHitTesting(false)
, alignment: .top)
.clipped()
}
}
struct TestFlexibleStickyHeader_Previews: PreviewProvider {
static var previews: some View {
TestFlexibleStickyHeader()
}
}