Skip to content

Commit 5007490

Browse files
committed
Merge branch 'main' into @mbert/clickable-docs
2 parents 1cd3061 + 4768080 commit 5007490

4 files changed

Lines changed: 70 additions & 26 deletions

File tree

packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,13 @@ - (void)setCurrentPointerType:(RNGestureHandlerPointerType)pointerType
166166
{
167167
_pointerType = pointerType;
168168

169+
#if CHECK_TARGET(16_1)
169170
if (@available(iOS 16.1, *)) {
170171
if (((UIHoverGestureRecognizer *)self.recognizer).zOffset > 0.0) {
171172
_pointerType = RNGestureHandlerStylus;
172173
}
173174
}
175+
#endif
174176
}
175177

176178
- (RNGestureHandlerEventExtraData *)eventExtraData:(UIGestureRecognizer *)recognizer

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
inState:(RNGestureHandlerState)state
107107
fromManualStateChange:(BOOL)fromManualStateChange;
108108
- (BOOL)containsPointInView;
109+
- (BOOL)wantsToHandleEventsAtPoint:(CGPoint)point;
109110
- (RNGestureHandlerState)state;
110111
- (nullable RNGestureHandlerEventExtraData *)eventExtraData:(nonnull id)recognizer;
111112

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,33 @@ - (BOOL)containsPointInView
744744
return CGRectContainsPoint(hitFrame, location);
745745
}
746746

747+
- (BOOL)wantsToHandleEventsAtPoint:(CGPoint)point
748+
{
749+
RNGHUIView *viewToHitTest = _recognizer.view;
750+
751+
if ([self usesNativeOrVirtualDetector] && [_recognizer.view.subviews count] > 0) {
752+
viewToHitTest = _recognizer.view.subviews[0];
753+
point = [_recognizer.view convertPoint:point toView:viewToHitTest];
754+
}
755+
756+
if (_actionType == RNGestureHandlerActionTypeVirtualDetector && _virtualViewTag != nil) {
757+
// In this case, logic detector is attached to the DetectorView, which has a single subview representing
758+
// the actual target view in the RN hierarchy
759+
if ([viewToHitTest respondsToSelector:@selector(touchEventEmitterAtPoint:)]) {
760+
// If the view has touchEventEmitterAtPoint: method, it can be used to determine the viewtag
761+
// of the view under the touch point
762+
facebook::react::SharedTouchEventEmitter eventEmitter =
763+
[(id<RCTTouchableComponentViewProtocol>)viewToHitTest touchEventEmitterAtPoint:point];
764+
auto viewUnderTouch = eventEmitter->getEventTarget()->getTag();
765+
766+
return viewUnderTouch == [_virtualViewTag intValue];
767+
}
768+
}
769+
770+
CGRect hitFrame = RNGHHitSlopInsetRect(viewToHitTest.bounds, _hitSlop);
771+
return CGRectContainsPoint(hitFrame, point);
772+
}
773+
747774
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
748775
{
749776
if ([_handlersToWaitFor count]) {

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

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -166,30 +166,6 @@ - (void)layout
166166
[self applyUnderlayCornerRadii];
167167
}
168168

169-
- (BOOL)shouldHandleTouch:(RNGHUIView *)view
170-
{
171-
if ([view isKindOfClass:[RNGestureHandlerButton class]]) {
172-
RNGestureHandlerButton *button = (RNGestureHandlerButton *)view;
173-
return button.userEnabled;
174-
}
175-
176-
// Certain subviews such as RCTViewComponentView have been observed to have disabled
177-
// accessibility gesture recognizers such as _UIAccessibilityHUDGateGestureRecognizer,
178-
// ostensibly set by iOS. Such gesture recognizers cause this function to return YES
179-
// even when the passed view is static text and does not respond to touches. This in
180-
// turn prevents the button from receiving touches, breaking functionality. To handle
181-
// such case, we can count only the enabled gesture recognizers when determining
182-
// whether a view should receive touches.
183-
NSPredicate *isEnabledPredicate = [NSPredicate predicateWithFormat:@"isEnabled == YES"];
184-
NSArray *enabledGestureRecognizers = [view.gestureRecognizers filteredArrayUsingPredicate:isEnabledPredicate];
185-
186-
#if !TARGET_OS_OSX
187-
return [view isKindOfClass:[UIControl class]] || [enabledGestureRecognizers count] > 0;
188-
#else
189-
return [view isKindOfClass:[NSControl class]] || [enabledGestureRecognizers count] > 0;
190-
#endif
191-
}
192-
193169
- (void)animateUnderlayToOpacity:(float)toOpacity duration:(NSTimeInterval)durationMs
194170
{
195171
_underlayLayer.opacity =
@@ -667,6 +643,44 @@ - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
667643
_isTouchInsideBounds = NO;
668644
}
669645

646+
- (BOOL)shouldHandleTouch:(RNGHUIView *)view atPoint:(CGPoint)point
647+
{
648+
if ([view isKindOfClass:[RNGestureHandlerButton class]]) {
649+
RNGestureHandlerButton *button = (RNGestureHandlerButton *)view;
650+
return button.userEnabled;
651+
}
652+
653+
// Certain subviews such as RCTViewComponentView have been observed to have disabled
654+
// accessibility gesture recognizers such as _UIAccessibilityHUDGateGestureRecognizer,
655+
// ostensibly set by iOS. Such gesture recognizers cause this function to return YES
656+
// even when the passed view is static text and does not respond to touches. This in
657+
// turn prevents the button from receiving touches, breaking functionality. To handle
658+
// such case, we can count only the enabled gesture recognizers when determining
659+
// whether a view should receive touches.
660+
NSPredicate *isEnabledPredicate = [NSPredicate predicateWithFormat:@"isEnabled == YES"];
661+
NSArray *enabledGestureRecognizers = [view.gestureRecognizers filteredArrayUsingPredicate:isEnabledPredicate];
662+
663+
BOOL gestureRecognizerWantsEvent = NO;
664+
for (UIGestureRecognizer *recognizer in enabledGestureRecognizers) {
665+
RNGestureHandler *handler = [RNGestureHandler findGestureHandlerByRecognizer:recognizer];
666+
if (handler != nil) {
667+
CGPoint pointInView = [self convertPoint:point toView:view];
668+
gestureRecognizerWantsEvent = [handler wantsToHandleEventsAtPoint:pointInView];
669+
} else {
670+
gestureRecognizerWantsEvent = YES;
671+
}
672+
if (gestureRecognizerWantsEvent) {
673+
break;
674+
}
675+
}
676+
677+
#if !TARGET_OS_OSX
678+
return [view isKindOfClass:[UIControl class]] || gestureRecognizerWantsEvent;
679+
#else
680+
return [view isKindOfClass:[NSControl class]] || [enabledGestureRecognizers count] > 0;
681+
#endif
682+
}
683+
670684
- (RNGHUIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
671685
{
672686
RNGestureHandlerPointerEvents pointerEvents = _pointerEvents;
@@ -680,7 +694,7 @@ - (RNGHUIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
680694
if (!subview.isHidden && subview.alpha > 0) {
681695
CGPoint convertedPoint = [subview convertPoint:point fromView:self];
682696
UIView *hitView = [subview hitTest:convertedPoint withEvent:event];
683-
if (hitView != nil && [self shouldHandleTouch:hitView]) {
697+
if (hitView != nil && [self shouldHandleTouch:hitView atPoint:point]) {
684698
return hitView;
685699
}
686700
}
@@ -693,7 +707,7 @@ - (RNGHUIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
693707
}
694708

695709
RNGHUIView *inner = [super hitTest:point withEvent:event];
696-
while (inner && ![self shouldHandleTouch:inner]) {
710+
while (inner && ![self shouldHandleTouch:inner atPoint:point]) {
697711
inner = inner.superview;
698712
}
699713
return inner;

0 commit comments

Comments
 (0)