@@ -65,7 +65,6 @@ class Core: NSObject, UIGestureRecognizerDelegate {
65
65
66
66
// Scroll handling
67
67
private var initialScrollOffset : CGPoint = . zero
68
- private var stopScrollDeceleration : Bool = false
69
68
private var scrollBounce = false
70
69
private var scrollIndictorVisible = false
71
70
private var scrollBounceThreshold : CGFloat = - 30.0
@@ -706,8 +705,10 @@ class Core: NSObject, UIGestureRecognizerDelegate {
706
705
}
707
706
708
707
// Determine whether the panel's dragging should be projected onto the scroll content scrolling
709
- stopScrollDeceleration = 0 > layoutAdapter. offsetFromMostExpandedAnchor
710
- if stopScrollDeceleration {
708
+ let stopScrollDeceleration = 0 > layoutAdapter. offsetFromMostExpandedAnchor
709
+ os_log ( msg, log: devLog, type: . debug, " panningEnd -- offsetFromMostExpandedAnchor = \( layoutAdapter. offsetFromMostExpandedAnchor) " )
710
+
711
+ if stopScrollDeceleration, state != layoutAdapter. mostExpandedState {
711
712
os_log ( msg, log: devLog, type: . debug, " panningEnd -- will stop scrolling at initialScrollOffset = \( initialScrollOffset) " )
712
713
DispatchQueue . main. async { [ weak self] in
713
714
guard let self = self else { return }
@@ -791,11 +792,42 @@ class Core: NSObject, UIGestureRecognizerDelegate {
791
792
792
793
initialSurfaceLocation = layoutAdapter. surfaceLocation
793
794
if state == layoutAdapter. mostExpandedState, let scrollView = scrollView {
794
- if surfaceView. grabberAreaContains ( location) {
795
+ let scrollFrame = scrollView. convert ( scrollView. bounds, to: nil )
796
+ let touchStartingPoint = surfaceView. convert ( initialLocation, to: nil )
797
+
798
+ ifLabel: if surfaceView. grabberAreaContains ( location) {
795
799
initialScrollOffset = scrollView. contentOffset
796
- } else {
800
+ } else if scrollFrame . contains ( touchStartingPoint ) {
797
801
let pinningOffset = contentOffsetForPinning ( of: scrollView)
798
802
803
+ // This code block handles the scenario where there's a navigation bar or toolbar
804
+ // above the tracking scroll view with corresponding content insets set, and users
805
+ // move the panel by interacting with these bars. One case of the scenario can be
806
+ // tested with 'Show Navigation Controller' in Samples.app
807
+ do {
808
+ // Adjust the location by subtracting scrollView's origin to reference the frame
809
+ // rectangle of the scroll view itself.
810
+ let _location = scrollView. convert ( location, from: surfaceView) - scrollView. bounds. origin
811
+
812
+ os_log ( msg, log: devLog, type: . debug, " startInteraction -- location in scroll view = \( _location) ) " )
813
+
814
+ // Keep the scroll content offset if the current touch position is inside its
815
+ // content inset area.
816
+ switch layoutAdapter. position {
817
+ case . top, . left:
818
+ let base = value ( of: scrollView. bounds. size)
819
+ if value ( of: pinningOffset) + ( base - value( of: _location) ) < 0 {
820
+ initialScrollOffset = scrollView. contentOffset
821
+ break ifLabel
822
+ }
823
+ case . bottom, . right:
824
+ if value ( of: pinningOffset) + value( of: _location) < 0 {
825
+ initialScrollOffset = scrollView. contentOffset
826
+ break ifLabel
827
+ }
828
+ }
829
+ }
830
+
799
831
// `initialScrollOffset` must be reset to the pinning offset because the value of `scrollView.contentOffset`,
800
832
// for instance, is a value in [-30, 0) on a bottom positioned panel with `allowScrollPanGesture(of:condition:)`.
801
833
// If it's not reset, the following logic to shift the surface frame will not work and then the scroll
@@ -814,6 +846,8 @@ class Core: NSObject, UIGestureRecognizerDelegate {
814
846
offset = - offsetDiff
815
847
}
816
848
}
849
+ } else {
850
+ initialScrollOffset = scrollView. contentOffset
817
851
}
818
852
os_log ( msg, log: devLog, type: . debug, " initial scroll offset -- \( initialScrollOffset) " )
819
853
}
@@ -916,8 +950,6 @@ class Core: NSObject, UIGestureRecognizerDelegate {
916
950
os_log ( msg, log: devLog, type: . debug, " finishAnimation -- scroll offset = \( scrollView. contentOffset) " )
917
951
}
918
952
919
- stopScrollDeceleration = false
920
-
921
953
os_log ( msg, log: devLog, type: . debug, """
922
954
finishAnimation -- state = \( state) \
923
955
surface location = \( layoutAdapter. surfaceLocation) \
0 commit comments