|
1 | 1 | #ifdef RCT_NEW_ARCH_ENABLED
|
2 | 2 | #import <React/RCTFabricComponentsPlugins.h>
|
| 3 | +#import <React/RCTFabricSurface.h> |
3 | 4 | #import <React/RCTMountingTransactionObserving.h>
|
4 | 5 | #import <React/RCTSurfaceTouchHandler.h>
|
| 6 | +#import <React/RCTSurfaceView.h> |
5 | 7 | #import <React/UIView+React.h>
|
6 | 8 | #import <react/renderer/components/rnscreens/ComponentDescriptors.h>
|
7 | 9 | #import <react/renderer/components/rnscreens/EventEmitters.h>
|
8 | 10 | #import <react/renderer/components/rnscreens/Props.h>
|
9 | 11 | #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
|
| 12 | +#import "RCTSurfaceTouchHandler+RNSUtility.h" |
10 | 13 | #else
|
11 | 14 | #import <React/RCTBridge.h>
|
12 | 15 | #import <React/RCTRootContentView.h>
|
13 | 16 | #import <React/RCTShadowView.h>
|
14 | 17 | #import <React/RCTTouchHandler.h>
|
15 | 18 | #import <React/RCTUIManager.h>
|
16 | 19 | #import <React/RCTUIManagerUtils.h>
|
| 20 | +#import "RCTTouchHandler+RNSUtility.h" |
17 | 21 | #endif // RCT_NEW_ARCH_ENABLED
|
18 | 22 |
|
19 | 23 | #import "RNSScreen.h"
|
@@ -731,19 +735,43 @@ - (void)cancelTouchesInParent
|
731 | 735 | // item is close to an edge and we start pulling from edge we want the Touchable to be cancelled.
|
732 | 736 | // Without the below code the Touchable will remain active (highlighted) for the duration of back
|
733 | 737 | // gesture and onPress may fire when we release the finger.
|
| 738 | +#ifdef RCT_NEW_ARCH_ENABLED |
| 739 | + // On Fabric there is no view that exposes touchHandler above us in the view hierarchy, however it is still |
| 740 | + // utilised. `RCTSurfaceView` should be present above us, which hosts `RCTFabricSurface` instance, which in turn |
| 741 | + // hosts `RCTSurfaceTouchHandler` as a private field. When initialised, `RCTSurfaceTouchHandler` is attached to the |
| 742 | + // surface view as a gestureRecognizer <- and this is where we can lay our hands on it. |
734 | 743 | UIView *parent = _controller.view;
|
735 |
| - while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) |
| 744 | + while (parent != nil && ![parent isKindOfClass:RCTSurfaceView.class]) { |
736 | 745 | parent = parent.superview;
|
737 |
| - if (parent != nil) { |
738 |
| -#ifdef RCT_NEW_ARCH_ENABLED |
739 |
| - RCTSurfaceTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)]; |
| 746 | + } |
| 747 | + |
| 748 | + // This could be possible in modal context |
| 749 | + if (parent == nil) { |
| 750 | + return; |
| 751 | + } |
| 752 | + |
| 753 | + RCTSurfaceTouchHandler *touchHandler = nil; |
| 754 | + // Experimentation shows that RCTSurfaceTouchHandler is the only gestureRecognizer registered here, |
| 755 | + // so we should not be afraid of any performance hit here. |
| 756 | + for (UIGestureRecognizer *recognizer in parent.gestureRecognizers) { |
| 757 | + if ([recognizer isKindOfClass:RCTSurfaceTouchHandler.class]) { |
| 758 | + touchHandler = static_cast<RCTSurfaceTouchHandler *>(recognizer); |
| 759 | + } |
| 760 | + } |
| 761 | + |
| 762 | + [touchHandler rnscreens_cancelTouches]; |
740 | 763 | #else
|
| 764 | + // On Paper we can access touchHandler hosted by `RCTRootContentView` which should be above ScreenStack |
| 765 | + // in view hierarchy. |
| 766 | + UIView *parent = _controller.view; |
| 767 | + while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) { |
| 768 | + parent = parent.superview; |
| 769 | + } |
| 770 | + if (parent != nil) { |
741 | 771 | RCTTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)];
|
742 |
| -#endif |
743 |
| - [touchHandler setEnabled:NO]; |
744 |
| - [touchHandler setEnabled:YES]; |
745 |
| - [touchHandler reset]; |
| 772 | + [touchHandler rnscreens_cancelTouches]; |
746 | 773 | }
|
| 774 | +#endif // RCT_NEW_ARCH_ENABLED |
747 | 775 | }
|
748 | 776 |
|
749 | 777 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
|
|
0 commit comments