From e5b703de660eb10fb4d7013fc7799cef8c5f4b72 Mon Sep 17 00:00:00 2001 From: Brian Floersch Date: Mon, 23 May 2022 21:57:11 -0400 Subject: [PATCH] finger tracking improvements --- Package.resolved | 16 +++++++++++++ Sources/Refresher/Refresher.swift | 38 ++++++++++++------------------- 2 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 Package.resolved diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..778d5db --- /dev/null +++ b/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "Introspect", + "repositoryURL": "https://github.com/siteline/SwiftUI-Introspect.git", + "state": { + "branch": null, + "revision": "f2616860a41f9d9932da412a8978fec79c06fe24", + "version": "0.1.4" + } + } + ] + }, + "version": 1 +} diff --git a/Sources/Refresher/Refresher.swift b/Sources/Refresher/Refresher.swift index 7b0d054..a3bde6d 100644 --- a/Sources/Refresher/Refresher.swift +++ b/Sources/Refresher/Refresher.swift @@ -90,12 +90,12 @@ public struct RefreshableScrollView: View { @State var state = RefresherState() @State var distance: CGFloat = 0 @State var rawDistance: CGFloat = 0 - @State var canRefresh = true private var style: Style private var config: Config @State private var uiScrollView: UIScrollView? - @State private var showRefreshControl = true + @State private var isRefresherVisible = true + @State private var isFingerDown = false init( axes: Axis.Set = .vertical, @@ -127,12 +127,13 @@ public struct RefreshableScrollView: View { return 0 } + private var isTracking: Bool { + guard let scrollView = uiScrollView else { return false } + return scrollView.isTracking + } + private var showRefreshControls: Bool { - guard let scrollView = uiScrollView else { - return false - } - - return scrollView.isTracking || showRefreshControl + return isFingerDown || isRefresherVisible } @ViewBuilder @@ -196,31 +197,22 @@ public struct RefreshableScrollView: View { } private func offsetChanged(_ val: CGFloat) { - guard showRefreshControls else { - return - } - + isFingerDown = isTracking distance = val - headerInset - - if distance < 1 { - canRefresh = true - } - state.dragPosition = normalize(from: 0, to: config.refreshAt, by: distance) + if case .refreshing = state.mode { return } - if !canRefresh { return } - - guard distance > 0 else { - set(mode: .notRefreshing) - showRefreshControl = false + guard distance > 0, showRefreshControls else { + state.mode = .notRefreshing + isRefresherVisible = false return } - showRefreshControl = true + + isRefresherVisible = true if distance >= config.refreshAt { UIImpactFeedbackGenerator(style: .medium).impactOccurred() set(mode: .refreshing) - canRefresh = false refreshAction { DispatchQueue.main.asyncAfter(deadline: .now() + config.holdTime) {