Skip to content

Let a gesture area's swipe win over iOS 26's swipe back from mid-screen - #181

Merged
simonhamp merged 1 commit into
mainfrom
fix/ios-swipe-beats-content-pop
Oct 28, 2026
Merged

simonhamp merged 1 commit into
mainfrom
fix/ios-swipe-beats-content-pop

Conversation

@simonhamp

Copy link
Copy Markdown
Member

On iOS 26 a pushed screen can be swiped back from anywhere in it, not only from the left edge. That's UINavigationController.interactiveContentPopGestureRecognizer. A native:gesture-area with @swipe recognizes alongside every other gesture, so a right swipe on it fires @swipe with "right" and starts popping the screen as well. In NativePHP/dev-null-app#102, where your own messages swipe right to show their actions, the thread slid back to the inbox.

Fix

The swipe recognizers' delegate now makes the navigation controller's content pop wait for the area's left and right swipe recognizers to fail, through gestureRecognizer(_:shouldBeRequiredToFailBy:). It finds the navigation controller by walking up the responder chain from the area, and only does this on iOS 26 and later. A horizontal swipe that starts in the area fires @swipe and the screen stays where it is.

  • The edge swipe back is a separate recognizer (interactivePopGestureRecognizer) and isn't touched. It still pops over an area with @swipe.
  • An area without @swipe has no swipe recognizers, so nothing changes for it.
  • Up and down swipes don't hold up the pop.

Worth a look

Inside an area with @swipe, a right drag from mid-screen no longer pops at all. UISwipeGestureRecognizer accepted even a slow 1.5 s drag as a swipe, so the pop never got its turn. The way back from there is the edge swipe or the back button. That seems right for an area that asked for swipes, but it is a change.

Tested

iPhone 17 Pro simulator on iOS 26.2. The test screen was in the dev-null app, pushed from a home screen, with a gesture area around a long pressable bubble and a pressable around another gesture area.

On main, a quick right swipe on the bubble fired @swipe and popped the screen back to home.

On this branch:

Gesture Result
Quick right swipe on the bubble @swipe right, screen stays
Slow (1.5 s) right drag on the bubble @swipe right, screen stays
Left swipe on the bubble @swipe left, screen stays
Right swipe inside the pressable around a gesture area @swipe right, screen stays, no press
Right drag from mid-screen over plain content pops
Edge swipe starting over the bubble pops, no @swipe

Debug builds don't catch Swift's type-substitution limit, so I also ran an unsigned Release build for a device. It succeeds:

xcodebuild -workspace nativephp/ios/NativePHP.xcworkspace -scheme NativePHP -configuration Release -destination 'generic/platform=iOS' CODE_SIGNING_ALLOWED=NO build

Android has its own swipe fix on a separate branch (fix/android-swipe-consumes-tap, where a swipe also tapped a pressable). This PR only touches resources/ios/NativeUIGestureAreaRenderer.swift.

Once this is tagged, dev-null-app (NativePHP/dev-null-app#102) needs a lock bump to pick it up.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simonhamp
simonhamp marked this pull request as ready for review October 28, 2026 17:00
@simonhamp
simonhamp merged commit 203e3c2 into main Oct 28, 2026
4 checks passed
@simonhamp
simonhamp deleted the fix/ios-swipe-beats-content-pop branch October 28, 2026 17:02
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.

1 participant