Skip to content

Commit

Permalink
Fix scroll locking behavior
Browse files Browse the repository at this point in the history
use a separate `scrollLocked` var instead of abusing the scrollView's properties to store the locked state;
fixes an issue where the scroll indicators were no longer visible because lockScrollView() was executed twice before unlockScrollView() was called (due to the user changing `showsVerticalScrollIndicator` mid-animation);
  • Loading branch information
futuretap committed Jan 11, 2024
1 parent be2be99 commit 107560e
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 18 deletions.
26 changes: 14 additions & 12 deletions Sources/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class Core: NSObject, UIGestureRecognizerDelegate {
private var scrollBounce = false
private var scrollIndictorVisible = false
private var scrollBounceThreshold: CGFloat = -30.0
private var scrollLocked = false

// MARK: - Interface

Expand Down Expand Up @@ -1050,29 +1051,25 @@ class Core: NSObject, UIGestureRecognizerDelegate {

private func lockScrollView(strict: Bool = false) {
guard let scrollView = scrollView else { return }
if scrollLocked {
os_log(msg, log: devLog, type: .debug, "Already scroll locked")
return
}

scrollBounce = scrollView.bounces
if !strict, shouldLooselyLockScrollView {
if scrollView.isLooselyLocked {
os_log(msg, log: devLog, type: .debug, "Already scroll locked loosely.")
return
}
// Don't change its `bounces` property. If it's changed, it will cause its scroll content offset jump at
// the most expanded anchor position while seamlessly scrolling content. This problem only occurs where its
// content mode is `.fitToBounds` and the tracking scroll content is smaller than the content view size.
// The reason why is because `bounces` prop change leads to the "content frame" change on `.fitToBounds`.
// See also https://github.com/scenee/FloatingPanel/issues/524.
} else {
if scrollView.isLocked {
os_log(msg, log: devLog, type: .debug, "Already scroll locked.")
return
}

scrollBounce = scrollView.bounces
scrollView.bounces = false
}
os_log(msg, log: devLog, type: .debug, "lock scroll view")

scrollView.isDirectionalLockEnabled = true
scrollLocked = true
scrollView.isDirectionalLockEnabled = true

switch layoutAdapter.position {
case .top, .bottom:
Expand All @@ -1085,9 +1082,14 @@ class Core: NSObject, UIGestureRecognizerDelegate {
}

private func unlockScrollView() {
guard let scrollView = scrollView, scrollView.isLocked else { return }
guard let scrollView = scrollView else { return }
if !scrollLocked {
os_log(msg, log: devLog, type: .debug, "Already scroll unlocked.")
return
}
os_log(msg, log: devLog, type: .debug, "unlock scroll view")

scrollLocked = false
scrollView.bounces = scrollBounce
scrollView.isDirectionalLockEnabled = false
switch layoutAdapter.position {
Expand Down
6 changes: 0 additions & 6 deletions Sources/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,6 @@ extension UIGestureRecognizer.State: CustomDebugStringConvertible {
#endif

extension UIScrollView {
var isLocked: Bool {
return !showsVerticalScrollIndicator && !bounces && isDirectionalLockEnabled
}
var isLooselyLocked: Bool {
return !showsVerticalScrollIndicator && isDirectionalLockEnabled
}
var fp_contentOffsetMax: CGPoint {
return CGPoint(x: max((contentSize.width + adjustedContentInset.right) - bounds.width, 0.0),
y: max((contentSize.height + adjustedContentInset.bottom) - bounds.height, 0.0))
Expand Down

0 comments on commit 107560e

Please sign in to comment.