Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.view.MotionEvent
import android.view.MotionEvent.PointerCoords
import android.view.MotionEvent.PointerProperties
import android.view.View
import androidx.core.view.isNotEmpty
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReadableMap
Expand Down Expand Up @@ -384,18 +385,37 @@ open class GestureHandler {
}
}

x = adaptedTransformedEvent.x
y = adaptedTransformedEvent.y
numberOfPointers = adaptedTransformedEvent.pointerCount
isWithinBounds = isWithinBounds(view, x, y)
if (shouldCancelWhenOutside && !isWithinBounds) {
if (state == STATE_ACTIVE) {
cancel()
} else if (state == STATE_BEGAN) {

// TODO: this is likely wrong, and the transformed event itself should be
// in the coordinate system of the child view, but I'm not sure of the
// consequences
if (view is RNGestureHandlerDetectorView && (view as RNGestureHandlerDetectorView).isNotEmpty()) {
val detector = view as RNGestureHandlerDetectorView
val outPoint = PointF()
GestureHandlerOrchestrator.transformPointToChildViewCoords(
adaptedTransformedEvent.x,
adaptedTransformedEvent.y,
detector,
detector.getChildAt(0),
outPoint,
)
x = outPoint.x
y = outPoint.y
isWithinBounds = isWithinBounds(detector.getChildAt(0), x, y)
Comment thread
j-piasecki marked this conversation as resolved.
} else {
x = adaptedTransformedEvent.x
y = adaptedTransformedEvent.y
isWithinBounds = isWithinBounds(view, x, y)
}

if (shouldCancelWhenOutside) {
if (!isWithinBounds && (state == STATE_ACTIVE || state == STATE_BEGAN)) {
fail()
return
}
return
}

lastAbsolutePositionX = GestureUtils.getLastPointerX(adaptedTransformedEvent, true)
lastAbsolutePositionY = GestureUtils.getLastPointerY(adaptedTransformedEvent, true)
lastEventOffsetX = adaptedTransformedEvent.rawX - adaptedTransformedEvent.x
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,13 +750,7 @@ class GestureHandlerOrchestrator(
return isLeafOrTransparent && isTransformedTouchPointInView(coords[0], coords[1], view)
}

private fun transformPointToChildViewCoords(
x: Float,
y: Float,
parent: ViewGroup,
child: View,
outLocalPoint: PointF,
) {
fun transformPointToChildViewCoords(x: Float, y: Float, parent: ViewGroup, child: View, outLocalPoint: PointF) {
var localX = x + parent.scrollX - child.left
var localY = y + parent.scrollY - child.top
val matrix = child.matrix
Expand Down
13 changes: 10 additions & 3 deletions packages/react-native-gesture-handler/apple/RNGestureHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,16 @@ - (void)reset

- (BOOL)containsPointInView
{
CGPoint pt = [_recognizer locationInView:_recognizer.view];
CGRect hitFrame = RNGHHitSlopInsetRect(_recognizer.view.bounds, _hitSlop);
return CGRectContainsPoint(hitFrame, pt);
RNGHUIView *viewToHitTest = _recognizer.view;

if (_shouldCancelWhenOutside && [self usesNativeOrVirtualDetector] && [_recognizer.view.subviews count] > 0) {
viewToHitTest = _recognizer.view.subviews[0];
}

CGPoint location = [_recognizer locationInView:viewToHitTest];
CGRect hitFrame = RNGHHitSlopInsetRect(viewToHitTest.bounds, _hitSlop);

return CGRectContainsPoint(hitFrame, location);
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
Expand Down
Loading