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 11, 2023
1 parent a917d6a commit bcfc17b
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 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,10 @@ class Core: NSObject, UIGestureRecognizerDelegate {
if surfaceView.grabberAreaContains(gestureRecognizer.location(in: surfaceView)) {
return false
}
return allowScrollPanGesture(for: scrollView)
guard state == layoutAdapter.mostExpandedState else { return false }
// 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 +460,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 +811,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,16 +1110,15 @@ class Core: NSObject, UIGestureRecognizerDelegate {
}
}

private func allowScrollPanGesture(for scrollView: UIScrollView) -> Bool {
guard state == layoutAdapter.mostExpandedState else { return false }
private func allowScrollPanGesture(of scrollView: UIScrollView, condition: (_ offsetY: CGFloat) -> Bool) -> Bool {
var offsetY: CGFloat = 0
switch layoutAdapter.position {
case .top, .left:
offsetY = value(of: scrollView.fp_contentOffsetMax - scrollView.contentOffset)
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 bcfc17b

Please sign in to comment.