Skip to content

fix(ios): yield to the navigation back gesture on the first page - #1195

Open
abulenok wants to merge 3 commits into
callstack:mainfrom
abulenok:fix/ios-yield-to-back-gesture
Open

abulenok wants to merge 3 commits into
callstack:mainfrom
abulenok:fix/ios-yield-to-back-gesture

Conversation

@abulenok

@abulenok abulenok commented Oct 20, 2026 •

Copy link
Copy Markdown

Summary

The SwiftUI pager's collection view claimed every horizontal drag, so react-native-screens' full-screen back swipe (its own pan recognizer before iOS 26, interactiveContentPopGestureRecognizer on iOS 26) never won, even on the first page. Recognizing simultaneously does not help because UIKit still hands the touch to the scroll view, so the pan has to be refused before it begins. UIKit only asks the scroll view itself in gestureRecognizerShouldBegin, so the introspected collection view gets a runtime subclass, the same approach disableSafeArea() uses.

The pan is refused only on page 0 of a horizontal pager, only in the back direction, and only while the nearest navigation controller can pop. iOS 26 also attaches UIScrollViewPagingSwipeGestureRecognizer to paging scroll views, which flips a page on a quick flick even when the pan never begins; it is refused under the same conditions.

Fixes #1050
The implementation is based on @nickbvr comment #1050 (comment)

Test Plan

What's required for testing (prerequisites)?

What are the steps to reproduce (after prerequisites)?

Compatibility

OS Implemented
iOS ✅
Android ❌

Checklist

  • I have tested this on a device and a simulator
  • I added the documentation in README.md
  • I updated the typed files (TS and Flow)

The SwiftUI pager's collection view claimed every horizontal drag, so
react-native-screens' full-screen back swipe (its own pan recognizer before
iOS 26, interactiveContentPopGestureRecognizer on iOS 26) never won, even on
the first page. Recognizing simultaneously does not help because UIKit still
hands the touch to the scroll view, so the pan has to be refused before it
begins. UIKit only asks the scroll view itself in gestureRecognizerShouldBegin,
so the introspected collection view gets a runtime subclass, the same approach
disableSafeArea() uses.

The pan is refused only on page 0 of a horizontal pager, only in the back
direction, and only while the nearest navigation controller can pop. iOS 26
also attaches UIScrollViewPagingSwipeGestureRecognizer to paging scroll views,
which flips a page on a quick flick even when the pan never begins; it is
refused under the same conditions.

Fixes callstack#1050

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Arbitration misses iOS 15’s embedded paging scroller and suppresses overdrag when no eligible back gesture is available.

2 open issues
What changed in this PR

Updates the SwiftUI iOS pager to yield first-page back swipes to navigation, addressing #1050.

Changes:

  • Tracks pager state for gesture arbitration.
  • Adds runtime overrides for paging pans and iOS 26 paging-swipe recognizers.
File Description
ios/​PagerView.swift Attaches the observer and synchronizes pager state.
ios/​PagerGestureObserver.swift Implements direction-aware back-gesture arbitration.

Review effort: Balanced

Comment thread ios/PagerGestureObserver.swift Outdated
Comment thread ios/PagerView.swift
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] react-native-screens v4.19.0 breaks the global back swipe gesture on pager views

2 participants