Skip to content

Commit dab2f5c

Browse files
committed
Handle multiple detector children explicitly
1 parent 310d913 commit dab2f5c

3 files changed

Lines changed: 13 additions & 10 deletions

File tree

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import android.view.MotionEvent
99
import android.view.MotionEvent.PointerCoords
1010
import android.view.MotionEvent.PointerProperties
1111
import android.view.View
12-
import androidx.core.view.isNotEmpty
1312
import com.facebook.react.bridge.Arguments
1413
import com.facebook.react.bridge.ReactContext
1514
import com.facebook.react.bridge.ReadableMap
@@ -51,15 +50,17 @@ open class GestureHandler {
5150
/**
5251
* The view whose coordinate space should be used when reporting event positions to JS.
5352
*
54-
* Handlers attached via the V3 NativeDetector are registered against the DetectorView
55-
* which never carries user-applied transforms — those live on the detector's single child.
56-
* Descending one level keeps reported coordinates consistent with V2 and the V3
57-
* InterceptingGestureDetector path. For all other attachment styles this is just [view].
53+
* Handlers attached via the V3 NativeDetector are registered against the DetectorView wrapper,
54+
* which never carries user-applied transforms — those live on its child. When the detector has
55+
* exactly one child we descend into it so reported coordinates match the visible (transformed)
56+
* view, the same coordinate space V2 and the V3 InterceptingGestureDetector report in. With
57+
* multiple children there is no JS-side way to disambiguate which child caught the pointer,
58+
* so we keep the detector itself as the reference frame.
5859
*/
5960
val coordinateView: View?
6061
get() {
6162
val v = view
62-
return if (v is RNGestureHandlerDetectorView && v.isNotEmpty()) {
63+
return if (v is RNGestureHandlerDetectorView && v.childCount == 1) {
6364
v.getChildAt(0)
6465
} else {
6566
v

packages/react-native-gesture-handler/apple/RNGestureHandler.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@
9191
/**
9292
The view whose coordinate space should be used when reporting event positions to JS.
9393
Handlers attached via the V3 NativeDetector are bound to the `RNGestureHandlerDetector` wrapper,
94-
which never carries user-applied transforms — those live on the detector's single subview.
95-
Descending one level keeps reported coordinates consistent with V2 and the V3
96-
InterceptingGestureDetector path. For all other attachment styles this is just `recognizer.view`.
94+
which never carries user-applied transforms — those live on its child. When the detector has
95+
exactly one subview we descend into it so reported coordinates match the visible (transformed)
96+
view, the same coordinate space V2 and the V3 InterceptingGestureDetector report in. With
97+
multiple subviews there is no JS-side way to disambiguate which child caught the pointer, so we
98+
keep the detector itself as the reference frame.
9799
*/
98100
@property (nonatomic, readonly, nullable) RNGHUIView *coordinateView;
99101

packages/react-native-gesture-handler/apple/RNGestureHandler.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ - (RNGHUIView *)coordinateView
311311
{
312312
RNGHUIView *recognizerView = _recognizer.view;
313313
if ([self usesNativeOrVirtualDetector] && recognizerView == self.hostDetectorView &&
314-
recognizerView.subviews.count > 0) {
314+
recognizerView.subviews.count == 1) {
315315
return recognizerView.subviews[0];
316316
}
317317
return recognizerView;

0 commit comments

Comments
 (0)