@@ -46,6 +46,7 @@ import platform.CoreGraphics.CGPoint
4646import platform.CoreGraphics.CGRectIsEmpty
4747import platform.CoreGraphics.CGRectZero
4848import platform.Foundation.NSSelectorFromString
49+ import platform.Foundation.NSStringFromClass
4950import platform.UIKit.UIEvent
5051import platform.UIKit.UIEventTypeTouches
5152import platform.UIKit.UIGestureRecognizer
@@ -66,6 +67,7 @@ import platform.UIKit.UIView
6667import platform.UIKit.endEditing
6768import platform.UIKit.setAccessibilityElements
6869import platform.UIKit.setState
70+ import platform.darwin.NSObject
6971
7072/* *
7173 * A reason for why touches are sent to Compose
@@ -295,7 +297,7 @@ private class TouchesGestureRecognizer(
295297 return if (isInChildHierarchy(preventedGestureRecognizer.view)) {
296298 super .canPreventGestureRecognizer(preventedGestureRecognizer)
297299 } else if (preventedGestureRecognizer is UIScreenEdgePanGestureRecognizer ) {
298- false
300+ preventedGestureRecognizer.isUINavigationControllerContentSwipeGestureRecognizer()
299301 } else {
300302 state == UIGestureRecognizerStatePossible || state.isOngoing
301303 }
@@ -872,3 +874,21 @@ private fun UIView?.hasTrackingUIScrollView(): Boolean {
872874 }
873875 return false
874876}
877+
878+ /* *
879+ * Detects the private UIKit recognizer that drives iOS 26 full-width `UINavigationController`
880+ * swipe-back interaction. It is a subclass of `UIScreenEdgePanGestureRecognizer` which can start
881+ * anywhere across the horizontal axis of the screen.
882+ *
883+ * Compose needs to be able to prevent this recognizer after Compose content consumes horizontal
884+ * movement, for example when a `HorizontalPager` handles the drag. Without that, UIKit can start
885+ * the navigation pop transition first and cancel Compose's touch stream.
886+ */
887+ private fun UIGestureRecognizer.isUINavigationControllerContentSwipeGestureRecognizer (): Boolean =
888+ available(OS .Ios to OSVersion (major = 26 )) &&
889+ this is UIScreenEdgePanGestureRecognizer &&
890+ className() == " _UIParallaxTransitionPanGestureRecognizer" &&
891+ name == " UINavigationController.contentSwipe"
892+
893+ @OptIn(BetaInteropApi ::class )
894+ private fun NSObject.className () = this .`class `()?.let { NSStringFromClass (it) }
0 commit comments