diff --git a/packages/docs-gesture-handler/docs/core-components/gesture-detector.mdx b/packages/docs-gesture-handler/docs/core-components/gesture-detector.mdx index 16ac8c3bf9..d5991fa398 100644 --- a/packages/docs-gesture-handler/docs/core-components/gesture-detector.mdx +++ b/packages/docs-gesture-handler/docs/core-components/gesture-detector.mdx @@ -177,6 +177,82 @@ const styles = StyleSheet.create({ `}/> +#### Views reordered during a gesture + +When a re-render changes `GestureDetector`'s place in the view hierarchy (e.g., a drag-to-reorder list puts the held row at a new index), the renderer may detach the view and reattach it, which cancels the active gesture. + +On Android, you can keep the gesture alive by wrapping the list in `InterceptingGestureDetector` and using `VirtualGestureDetector` for each row. The gesture is then attached through the list's detector, which stays in place. + +On iOS and web the system cancels the gesture of a reattached view regardless of the detector used. + + void }; + +function Row({ id, onGrab }: RowProps) { + const pan = usePanGesture({ + runOnJS: true, + onActivate: () => onGrab(id), + }); + + return ( + + + {id} + + + ); +} + +export default function App() { + const [rows, setRows] = useState(['A', 'B', 'C', 'D']); + + const onGrab = (id: string) => + setRows((current) => [id, ...current.filter((row) => row !== id)]); + + return ( + + + id} + renderItem={({ item }) => } + /> + + + ); +} + +const styles = StyleSheet.create({ + container: { flex: 1, padding: 16 }, + row: { + height: 80, + marginBottom: 12, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#001A72', + }, + text: { + color: 'white', + fontWeight: 'bold', + fontSize: 20, + }, +}); +`}/> + + ## Properties ### gesture diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index 45cd592f9a..5ae03bf5c0 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -271,9 +271,9 @@ Full changes are as follows: | `blocksHandlers` | `block` | -## Migrating components relying on view hierarchy +## Migrating to virtual detectors -Certain components, such as `SVG`, depend on the view hierarchy to function correctly. In Gesture Handler 3, `GestureDetector` disrupts these hierarchies. To resolve this issue, two new detectors have been introduced: [`InterceptingGestureDetector`](/docs/core-components/gesture-detectors#interceptinggesturedetector) and [`VirtualGestureDetector`](/docs/core-components/gesture-detectors#virtualgesturedetector). +In Gesture Handler 3, `GestureDetector` is a host view. This has two consequences: it disrupts components that depend on the view hierarchy, such as `SVG`, and it is detached and reattached when its place in the hierarchy changes, which cancels an active gesture. To handle both cases, two new detectors have been introduced: [`InterceptingGestureDetector`](/docs/core-components/gesture-detectors#interceptinggesturedetector) and [`VirtualGestureDetector`](/docs/core-components/gesture-detectors#virtualgesturedetector). :::danger Detectors order `VirtualGestureDetector` has to be a descendant of `InterceptingGestureDetector`. @@ -308,6 +308,45 @@ code2={ `} /> +### Migrating views reordered during a gesture + +In Gesture Handler 2, a gesture on Android survived its view being reordered mid-gesture, for example a drag-to-reorder list putting the held row at a new index. To keep that behavior, use `InterceptingGestureDetector` and `VirtualGestureDetector`. See [Views reordered during a gesture](/docs/core-components/gesture-detectors#views-reordered-during-a-gesture) for details. + + + + + ); +} + + } /> +`} +code2={ +` +function Row() { + const pan = usePanGesture(); + + return ( + + + + ); +} + + + } /> + +`} +/> + ## Old components ### Buttons