Skip to content

Commit

Permalink
Fix an issue where a tracking scroll content stops and the panel does…
Browse files Browse the repository at this point in the history
…n't move

Resolve #530
  • Loading branch information
scenee committed Jul 8, 2023
1 parent a917d6a commit 3f386d6
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions Sources/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Core: NSObject, UIGestureRecognizerDelegate {
private var stopScrollDeceleration: Bool = false
private var scrollBounce = false
private var scrollIndictorVisible = false
private var scrollBounceThreshold: CGFloat = -30.0

// MARK: - Interface

Expand Down Expand Up @@ -337,7 +338,9 @@ class Core: NSObject, UIGestureRecognizerDelegate {
if surfaceView.grabberAreaContains(gestureRecognizer.location(in: surfaceView)) {
return false
}
return allowScrollPanGesture(for: scrollView)
// The condition where offsetY > 0 must not include here. Because this condition prevents the panel
// pan gesture recognizer when a user start scrolling content from more than 0 offset.
return allowScrollPanGesture(of: scrollView) { offsetY in offsetY <= scrollBounceThreshold }
default:
return false
}
Expand Down Expand Up @@ -456,21 +459,24 @@ class Core: NSObject, UIGestureRecognizerDelegate {
}
} else {
if state == layoutAdapter.mostExpandedState {
let allowScroll = allowScrollPanGesture(of: scrollView) { offsetY in
offsetY <= scrollBounceThreshold || offsetY > 0
}
switch layoutAdapter.position {
case .top, .left:
if velocity < 0, !allowScrollPanGesture(for: scrollView) {
if velocity < 0, !allowScroll {
lockScrollView(strict: true)
}
if velocity > 0, allowScrollPanGesture(for: scrollView) {
if velocity > 0, allowScroll {
unlockScrollView()
}
case .bottom, .right:
// Hide a scroll indicator just before starting an interaction by swiping a panel down.
if velocity > 0, !allowScrollPanGesture(for: scrollView) {
if velocity > 0, !allowScroll {
lockScrollView(strict: true)
}
// Show a scroll indicator when an animation is interrupted at the top and content is scrolled up
if velocity < 0, allowScrollPanGesture(for: scrollView) {
if velocity < 0, allowScroll {
unlockScrollView()
}
}
Expand Down Expand Up @@ -804,7 +810,7 @@ class Core: NSObject, UIGestureRecognizerDelegate {
} else {
let pinningOffset = contentOffsetForPinning(of: scrollView)

// `scrollView.contentOffset` can be a value in [-30, 0) at this time by `allowScrollPanGesture(for:)`.
// `scrollView.contentOffset` can be a value in [-30, 0) at this time by `allowScrollPanGesture(of:condition:)`.
// Therefore the initial scroll offset must be reset to the pinning offset. Otherwise, the following
// `Fit the surface bounds` logic don't working and also the scroll content offset can be invalid.
initialScrollOffset = pinningOffset
Expand Down Expand Up @@ -1103,7 +1109,7 @@ class Core: NSObject, UIGestureRecognizerDelegate {
}
}

private func allowScrollPanGesture(for scrollView: UIScrollView) -> Bool {
private func allowScrollPanGesture(of scrollView: UIScrollView, condition: (_ offsetY: CGFloat) -> Bool) -> Bool {
guard state == layoutAdapter.mostExpandedState else { return false }
var offsetY: CGFloat = 0
switch layoutAdapter.position {
Expand All @@ -1112,7 +1118,7 @@ class Core: NSObject, UIGestureRecognizerDelegate {
case .bottom, .right:
offsetY = value(of: scrollView.contentOffset - contentOffsetForPinning(of: scrollView))
}
return offsetY <= -30.0 || offsetY > 0
return condition(offsetY)
}

// MARK: - UIPanGestureRecognizer Intermediation
Expand Down

0 comments on commit 3f386d6

Please sign in to comment.