@@ -12,65 +12,72 @@ class PagerGestureDelegate: NSObject, UIGestureRecognizerDelegate {
1212 private var gestureObserver : NSKeyValueObservation ?
1313
1414 func gestureRecognizer( _ gestureRecognizer: UIGestureRecognizer , shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer ) -> Bool {
15- // iOS 26+ full-screen back gesture (interactiveContentPopGestureRecognizer)
15+ // Get the navigation controller
16+ guard let collectionView = collectionView,
17+ let viewController = collectionView. reactViewController ( ) ,
18+ let navigationController = viewController. navigationController else {
19+ return false
20+ }
21+
22+ // Check if this is the pager's pan gesture
23+ guard gestureRecognizer == collectionView. panGestureRecognizer else {
24+ return false
25+ }
26+
27+ // Determine which navigation gesture recognizer to check
28+ var navGestureRecognizer : UIGestureRecognizer ? = navigationController. interactivePopGestureRecognizer
29+
30+ // iOS 26+ introduces interactiveContentPopGestureRecognizer for full-screen back gestures
1631 if #available( iOS 26 , * ) {
17- // Get the navigation controller's interactive content pop gesture recognizer
18- guard let collectionView = collectionView,
19- let viewController = collectionView. reactViewController ( ) ,
20- let navigationController = viewController. navigationController else {
21- return false
22- }
23-
24- // iOS 26 introduces interactiveContentPopGestureRecognizer for full-screen back gestures
25- // We need to check if this property exists and use it, otherwise fall back to standard behavior
26- let interactiveGesture : UIGestureRecognizer ?
27- if let contentPopGesture = navigationController. value ( forKey: " interactiveContentPopGestureRecognizer " ) as? UIGestureRecognizer {
28- interactiveGesture = contentPopGesture
29- } else {
30- // Fallback to standard interactivePopGestureRecognizer
31- interactiveGesture = navigationController. interactivePopGestureRecognizer
32+ // Try to access the new property safely using selector
33+ let selector = NSSelectorFromString ( " interactiveContentPopGestureRecognizer " )
34+ if navigationController. responds ( to: selector) ,
35+ let contentPopGesture = navigationController. perform ( selector) ? . takeUnretainedValue ( ) as? UIGestureRecognizer {
36+ navGestureRecognizer = contentPopGesture
3237 }
38+ }
39+
40+ // Check if the other gesture is the navigation back gesture
41+ guard let navGesture = navGestureRecognizer,
42+ otherGestureRecognizer == navGesture else {
43+ return false
44+ }
45+
46+ // Get velocity to determine swipe direction
47+ guard let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer else {
48+ return false
49+ }
50+
51+ let velocity = panGestureRecognizer. velocity ( in: collectionView)
52+ let isLTR = layoutDirection == . ltr
53+ let isBackGesture = ( isLTR && velocity. x > 0 ) || ( !isLTR && velocity. x < 0 )
54+
55+ // If on first page and performing back gesture, disable pager scroll to allow navigation
56+ if currentPage == 0 && isBackGesture {
57+ collectionView. panGestureRecognizer. isEnabled = false
3358
34- // Check if this is the pager's pan gesture and the other is the navigation back gesture
35- if gestureRecognizer == collectionView. panGestureRecognizer,
36- otherGestureRecognizer == interactiveGesture {
59+ // Observe gesture state to re-enable when gesture ends
60+ gestureObserver? . invalidate ( )
61+ gestureObserver = otherGestureRecognizer. observe ( \. state, options: [ . new] ) { [ weak self, weak collectionView] _, change in
62+ guard let self = self ,
63+ let collectionView = collectionView,
64+ let newState = change. newValue else { return }
3765
38- // Get velocity to determine swipe direction
39- guard let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer else {
40- return false
41- }
42-
43- let velocity = panGestureRecognizer. velocity ( in: collectionView)
44- let isLTR = layoutDirection == . ltr
45- let isBackGesture = ( isLTR && velocity. x > 0 ) || ( !isLTR && velocity. x < 0 )
46-
47- // If on first page and performing back gesture, disable pager scroll to allow navigation
48- if currentPage == 0 && isBackGesture {
49- collectionView. panGestureRecognizer. isEnabled = false
50-
51- // Observe gesture state to re-enable when gesture ends
52- gestureObserver? . invalidate ( )
53- gestureObserver = otherGestureRecognizer. observe ( \. state, options: [ . new] ) { [ weak self, weak collectionView] _, change in
54- guard let self = self ,
55- let collectionView = collectionView,
56- let newState = change. newValue else { return }
57-
58- // Re-enable pager scroll when navigation gesture ends
59- if newState == . ended || newState == . cancelled || newState == . failed {
60- collectionView. panGestureRecognizer. isEnabled = self . scrollEnabled
61- self . gestureObserver? . invalidate ( )
62- self . gestureObserver = nil
63- }
66+ // Re-enable pager scroll when navigation gesture ends
67+ if newState == . ended || newState == . cancelled || newState == . failed {
68+ // Ensure UIKit updates happen on main queue
69+ DispatchQueue . main. async {
70+ collectionView. panGestureRecognizer. isEnabled = self . scrollEnabled
6471 }
65- } else {
66- collectionView . panGestureRecognizer . isEnabled = scrollEnabled
72+ self . gestureObserver ? . invalidate ( )
73+ self . gestureObserver = nil
6774 }
68-
69- return true
7075 }
76+ } else {
77+ collectionView. panGestureRecognizer. isEnabled = scrollEnabled
7178 }
7279
73- return false
80+ return true
7481 }
7582
7683 deinit {
0 commit comments