-
Notifications
You must be signed in to change notification settings - Fork 0
/
PullToRefreshView.swift
69 lines (64 loc) · 2.71 KB
/
PullToRefreshView.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
59
60
61
62
63
64
65
66
67
68
69
import SwiftUI
struct PullToRefreshHack: View {
var coordinateSpaceName: String
var onRefresh: ()->Void
@State var needRefresh: Bool = false
@State var stillHolding:Bool = false
@State var pullAndHoldText = "pull down to refresh"
var body: some View {
GeometryReader { geo in
if (geo.frame(in: .named(coordinateSpaceName)).midY > 50) { //once they pull down 50px basically
Rectangle().frame(width: 1, height: 1).foregroundColor(.clear)
.onAppear {
pullAndHoldText = "keep holding..."
stillHolding = true;
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(750), execute: {
//start a timer, when timer completes, run this:
if stillHolding {
let generator = UINotificationFeedbackGenerator()
generator.prepare()
generator.notificationOccurred(.success)
withAnimation {
needRefresh = true
}
}
})
}
.onDisappear {
stillHolding = false
pullAndHoldText = "pull down to refresh"
}
} else if (geo.frame(in: .named(coordinateSpaceName)).maxY < 10) { //once they release it back up
Rectangle().frame(width: 1, height: 1).foregroundColor(.clear)
.onAppear {
if needRefresh {
withAnimation {
needRefresh = false
}
onRefresh()
}
}
}
HStack {
Spacer()
if needRefresh {
ActivityIndicator(isAnimating: .constant(true), style: .medium) //or put any 'refreshing' indicator of choice here
} else {
VStack{
Image(systemName: "arrow.down")
.font(.system(size: 20.0))
Text(pullAndHoldText).font(.custom("HelveticaNeue", size: 12))
}
}
Spacer()
}
}.padding(.top, -60)
}
}
struct PullToRefreshHack_Previews: PreviewProvider {
static var previews: some View {
ScrollView {
PullToRefreshHack(coordinateSpaceName: "bob", onRefresh: {})
}.coordinateSpace(name: "bob")
}
}