Skip to content

fix: dragging stops after a screen is detached and re-attached (gesture-handler v3)#573

Draft
MatiPl01 wants to merge 7 commits into
mainfrom
fix/gesture-handler-v3-stuck-drag
Draft

fix: dragging stops after a screen is detached and re-attached (gesture-handler v3)#573
MatiPl01 wants to merge 7 commits into
mainfrom
fix/gesture-handler-v3-stuck-drag

Conversation

@MatiPl01

Copy link
Copy Markdown
Owner

Summary

On iOS + the New Architecture, a sortable could stop recognizing drags - the dragged item gets "stuck", or a drag won't start - after its screen was detached and re-attached, for example bottom tabs with detachInactiveScreens={false}. This is issue #349.

The root cause is an upstream react-native-gesture-handler v2 limitation: after react-native-screens re-attaches the screen, the v2 GestureDetector loses its touch stream, so a drag never receives its touch-up/cancel and never ends. The gesture-handler team confirmed the v2 API can't be fixed for this and resolved it in the v3 hook API (see react-native-gesture-handler#3560).

Fix

A small backward-compatible gesture-handler integration (src/integrations/gesture-handler) that uses the v3 hook API (useManualGesture / useTapGesture / ...) when gesture-handler v3 is installed - which fixes #349 - and falls back to the existing v2 imperative builder otherwise. The version is detected once at module load, so the right gesture path is chosen without any runtime branching inside hooks:

// src/integrations/gesture-handler/index.ts
const hasHookApi =
  typeof (GestureHandler as { useManualGesture?: unknown }).useManualGesture ===
  'function';

const adapter = hasHookApi ? v3Adapter : v2Adapter;

export const useDragGesture = adapter.useDragGesture;

Not a breaking change: the peer range stays >=2.0.0 and the public types use only gesture names exported by both majors. The issue is New-Architecture-only; the Old Architecture (Paper) keeps the v2 path, where it never occurs and which gesture-handler v3 no longer supports.

Recording (iOS, New Architecture, gesture-handler v3)

Drag reorders an item, switch to the other tab and back, then drag again: it keeps working (this is where v2 would get stuck).

Closes #349

Drags could get stuck or stop starting after a screen was detached and re-attached on iOS + New Architecture (e.g. bottom tabs with detachInactiveScreens=false) - a gesture-handler v2 limitation (#349). The new gesture-handler integration uses the v3 hook API when installed and falls back to the v2 imperative builder otherwise, selected once at module load. Non-breaking: the peer range stays >=2.0.0 and public types use only gesture names exported by both majors.
@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
react-native-sortables-docs Ignored Ignored Preview Jun 28, 2026 9:41pm

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation fix labels Jun 27, 2026
@MatiPl01 MatiPl01 self-assigned this Jun 27, 2026
MatiPl01 added 2 commits June 27, 2026 23:11
Remove the as-unknown-as double casts (centralize gesture bridging in a single asSortableGesture helper plus narrowing casts) and trim the adapter comments to the non-obvious rationale only. No behavior change.
react-native-sortables is built against gesture-handler v3, so importing it in the example app's jest tests pulled in an unmocked v3 native module (RNGestureHandlerModule getEnforcing). Map every gesture-handler import to the single mocked instance the app already sets up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation example fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

items sometimes get "stuck" when dragging

1 participant