react-native-gesture-handler 2.32.0 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +27 -11
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +32 -33
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +144 -15
- package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +6 -3
- package/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt +23 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +4 -7
- package/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/react/Extensions.kt +3 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +2 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +9 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +8 -6
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt +2 -7
- package/apple/Handlers/RNFlingHandler.m +44 -4
- package/apple/Handlers/RNHoverHandler.m +24 -26
- package/apple/Handlers/RNLongPressHandler.m +4 -0
- package/apple/Handlers/RNPanHandler.m +44 -7
- package/apple/Handlers/RNTapHandler.m +35 -4
- package/apple/RNGHUIKit.h +10 -10
- package/apple/RNGestureHandler.h +2 -0
- package/apple/RNGestureHandler.mm +47 -6
- package/apple/RNGestureHandlerButton.mm +5 -3
- package/apple/RNGestureHandlerManager.mm +63 -6
- package/apple/RNGestureHandlerModule.mm +20 -0
- package/apple/RNGestureHandlerPointerTracker.m +64 -10
- package/apple/RNGestureHandlerPointerType.h +1 -0
- package/apple/RNManualActivationRecognizer.m +25 -6
- package/lib/commonjs/components/GestureComponents.js +21 -1
- package/lib/commonjs/components/GestureComponents.js.map +1 -1
- package/lib/commonjs/components/GestureHandlerButton.web.js +2 -1
- package/lib/commonjs/components/GestureHandlerButton.web.js.map +1 -1
- package/lib/commonjs/components/Pressable/Pressable.js +28 -3
- package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
- package/lib/commonjs/components/Pressable/index.js.map +1 -1
- package/lib/commonjs/components/ReanimatedDrawerLayout.js +4 -2
- package/lib/commonjs/components/ReanimatedDrawerLayout.js.map +1 -1
- package/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js +32 -9
- package/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
- package/lib/commonjs/components/Swipeable.js.map +1 -1
- package/lib/commonjs/components/Text.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableHighlight.js +1 -1
- package/lib/commonjs/components/touchables/TouchableHighlight.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableNativeFeedback.android.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableOpacity.js +1 -0
- package/lib/commonjs/components/touchables/TouchableOpacity.js.map +1 -1
- package/lib/commonjs/getShadowNodeFromRef.js +6 -2
- package/lib/commonjs/getShadowNodeFromRef.js.map +1 -1
- package/lib/commonjs/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.js +56 -11
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js +2 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useMountReactions.js +6 -0
- package/lib/commonjs/handlers/gestures/GestureDetector/useMountReactions.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js +3 -2
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gestureStateManager.web.js.map +1 -1
- package/lib/commonjs/handlers/gestures/panGesture.js +6 -3
- package/lib/commonjs/handlers/gestures/panGesture.js.map +1 -1
- package/lib/commonjs/hostInstance.js +39 -0
- package/lib/commonjs/hostInstance.js.map +1 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/mocks/mocks.js +1 -0
- package/lib/commonjs/mocks/mocks.js.map +1 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
- package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
- package/lib/commonjs/web/detectors/RotationGestureDetector.js +1 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js +3 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +9 -1
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js +8 -9
- package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/TapGestureHandler.js +1 -1
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +14 -0
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/commonjs/web/tools/WheelEventManager.js +4 -0
- package/lib/commonjs/web/tools/WheelEventManager.js.map +1 -1
- package/lib/module/components/GestureComponents.js +23 -2
- package/lib/module/components/GestureComponents.js.map +1 -1
- package/lib/module/components/GestureHandlerButton.web.js +2 -1
- package/lib/module/components/GestureHandlerButton.web.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +28 -3
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/Pressable/index.js.map +1 -1
- package/lib/module/components/ReanimatedDrawerLayout.js +4 -2
- package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -1
- package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +34 -11
- package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/components/Swipeable.js.map +1 -1
- package/lib/module/components/Text.js.map +1 -1
- package/lib/module/components/touchables/TouchableHighlight.js +2 -2
- package/lib/module/components/touchables/TouchableHighlight.js.map +1 -1
- package/lib/module/components/touchables/TouchableNativeFeedback.android.js.map +1 -1
- package/lib/module/components/touchables/TouchableOpacity.js +1 -0
- package/lib/module/components/touchables/TouchableOpacity.js.map +1 -1
- package/lib/module/getShadowNodeFromRef.js +7 -2
- package/lib/module/getShadowNodeFromRef.js.map +1 -1
- package/lib/module/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/Wrap.js +56 -11
- package/lib/module/handlers/gestures/GestureDetector/Wrap.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/index.js +2 -1
- package/lib/module/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useMountReactions.js +6 -0
- package/lib/module/handlers/gestures/GestureDetector/useMountReactions.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js +3 -2
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/module/handlers/gestures/gestureStateManager.web.js.map +1 -1
- package/lib/module/handlers/gestures/panGesture.js +6 -3
- package/lib/module/handlers/gestures/panGesture.js.map +1 -1
- package/lib/module/hostInstance.js +32 -0
- package/lib/module/hostInstance.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/mocks.js +3 -2
- package/lib/module/mocks/mocks.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
- package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
- package/lib/module/web/detectors/RotationGestureDetector.js +1 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js +3 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/NativeViewGestureHandler.js +9 -1
- package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/PanGestureHandler.js +8 -9
- package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/TapGestureHandler.js +1 -1
- package/lib/module/web/tools/GestureHandlerOrchestrator.js +14 -0
- package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/module/web/tools/WheelEventManager.js +4 -0
- package/lib/module/web/tools/WheelEventManager.js.map +1 -1
- package/lib/typescript/components/GestureButtons.d.ts +3 -1
- package/lib/typescript/components/GestureButtons.d.ts.map +1 -1
- package/lib/typescript/components/GestureButtonsProps.d.ts +10 -0
- package/lib/typescript/components/GestureButtonsProps.d.ts.map +1 -1
- package/lib/typescript/components/GestureComponents.d.ts +8 -7
- package/lib/typescript/components/GestureComponents.d.ts.map +1 -1
- package/lib/typescript/components/GestureComponents.web.d.ts +12 -4
- package/lib/typescript/components/GestureComponents.web.d.ts.map +1 -1
- package/lib/typescript/components/GestureHandlerButton.web.d.ts +2 -2
- package/lib/typescript/components/GestureHandlerButton.web.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/Pressable.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/PressableProps.d.ts +1 -1
- package/lib/typescript/components/Pressable/PressableProps.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/index.d.ts +1 -1
- package/lib/typescript/components/Pressable/index.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedDrawerLayout.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts.map +1 -1
- package/lib/typescript/components/Swipeable.d.ts.map +1 -1
- package/lib/typescript/components/touchables/TouchableHighlight.d.ts +1 -1
- package/lib/typescript/components/touchables/TouchableHighlight.d.ts.map +1 -1
- package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts +1 -1
- package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts.map +1 -1
- package/lib/typescript/components/touchables/TouchableOpacity.d.ts.map +1 -1
- package/lib/typescript/getShadowNodeFromRef.d.ts.map +1 -1
- package/lib/typescript/handlers/PanGestureHandler.d.ts +12 -0
- package/lib/typescript/handlers/PanGestureHandler.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/Wrap.d.ts +11 -0
- package/lib/typescript/handlers/gestures/GestureDetector/Wrap.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/index.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useDetectorUpdater.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useMountReactions.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useViewRefHandler.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts +8 -1
- package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/panGesture.d.ts +6 -3
- package/lib/typescript/handlers/gestures/panGesture.d.ts.map +1 -1
- package/lib/typescript/hostInstance.d.ts +10 -0
- package/lib/typescript/hostInstance.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/mocks/mocks.d.ts +67 -15
- package/lib/typescript/mocks/mocks.d.ts.map +1 -1
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +6 -7
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts.map +1 -1
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +9 -10
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts.map +1 -1
- package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +2 -2
- package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts.map +1 -1
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts.map +1 -1
- package/lib/typescript/web/handlers/PanGestureHandler.d.ts.map +1 -1
- package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +1 -0
- package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts.map +1 -1
- package/lib/typescript/web/tools/WheelEventManager.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/components/GestureButtonsProps.ts +14 -0
- package/src/components/GestureComponents.tsx +38 -7
- package/src/components/GestureHandlerButton.web.tsx +7 -3
- package/src/components/Pressable/Pressable.tsx +33 -4
- package/src/components/Pressable/PressableProps.tsx +1 -1
- package/src/components/Pressable/index.ts +1 -0
- package/src/components/ReanimatedDrawerLayout.tsx +4 -1
- package/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +49 -10
- package/src/components/Swipeable.tsx +6 -2
- package/src/components/Text.tsx +3 -3
- package/src/components/touchables/TouchableHighlight.tsx +4 -2
- package/src/components/touchables/TouchableNativeFeedback.android.tsx +8 -2
- package/src/components/touchables/TouchableOpacity.tsx +1 -0
- package/src/getShadowNodeFromRef.ts +11 -4
- package/src/handlers/PanGestureHandler.ts +15 -0
- package/src/handlers/gestures/GestureDetector/Wrap.tsx +78 -13
- package/src/handlers/gestures/GestureDetector/index.tsx +4 -1
- package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +4 -1
- package/src/handlers/gestures/GestureDetector/useMountReactions.ts +6 -0
- package/src/handlers/gestures/GestureDetector/useViewRefHandler.ts +5 -2
- package/src/handlers/gestures/gestureStateManager.web.ts +9 -1
- package/src/handlers/gestures/panGesture.ts +6 -3
- package/src/hostInstance.ts +57 -0
- package/src/index.ts +1 -0
- package/src/mocks/mocks.tsx +6 -2
- package/src/specs/NativeRNGestureHandlerModule.ts +16 -10
- package/src/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
- package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
- package/src/web/detectors/RotationGestureDetector.ts +1 -1
- package/src/web/handlers/LongPressGestureHandler.ts +3 -1
- package/src/web/handlers/NativeViewGestureHandler.ts +11 -2
- package/src/web/handlers/PanGestureHandler.ts +8 -11
- package/src/web/handlers/TapGestureHandler.ts +1 -1
- package/src/web/tools/GestureHandlerOrchestrator.ts +19 -0
- package/src/web/tools/WheelEventManager.ts +1 -0
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
#else
|
|
96
96
|
|
|
97
97
|
@interface RNBetterSwipeGestureRecognizer : NSGestureRecognizer {
|
|
98
|
-
|
|
98
|
+
// scheduled on mouseDown; fails the gesture if the fling doesn't complete within maxDuration
|
|
99
|
+
dispatch_block_t maxDurationTimeout;
|
|
99
100
|
int maxDuration;
|
|
100
101
|
int minVelocity;
|
|
101
102
|
double defaultAlignmentCone;
|
|
@@ -137,18 +138,34 @@
|
|
|
137
138
|
[_gestureHandler handleGesture:self];
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
- (void)triggerAction
|
|
142
|
+
{
|
|
143
|
+
[_gestureHandler handleGesture:self fromReset:NO];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
- (void)triggerActionFromReset
|
|
147
|
+
{
|
|
148
|
+
[_gestureHandler handleGesture:self fromReset:YES];
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
- (void)mouseDown:(NSEvent *)event
|
|
141
152
|
{
|
|
153
|
+
[_gestureHandler setCurrentPointerTypeToMouse];
|
|
154
|
+
[_gestureHandler reset];
|
|
142
155
|
[super mouseDown:event];
|
|
143
156
|
|
|
144
157
|
startPosition = [self locationInView:self.view];
|
|
145
158
|
startTime = CACurrentMediaTime();
|
|
146
159
|
|
|
160
|
+
[_gestureHandler.pointerTracker touchesBegan:[NSSet setWithObject:event] withEvent:event];
|
|
161
|
+
// Send the BEGAN event, mirroring what the iOS recognizer does in touchesBegan.
|
|
162
|
+
[self triggerAction];
|
|
163
|
+
|
|
147
164
|
self.state = NSGestureRecognizerStatePossible;
|
|
148
165
|
|
|
149
166
|
__weak typeof(self) weakSelf = self;
|
|
150
167
|
|
|
151
|
-
|
|
168
|
+
maxDurationTimeout = dispatch_block_create(0, ^{
|
|
152
169
|
__strong typeof(self) strongSelf = weakSelf;
|
|
153
170
|
|
|
154
171
|
if (strongSelf) {
|
|
@@ -159,13 +176,15 @@
|
|
|
159
176
|
dispatch_after(
|
|
160
177
|
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(maxDuration * NSEC_PER_SEC)),
|
|
161
178
|
dispatch_get_main_queue(),
|
|
162
|
-
|
|
179
|
+
maxDurationTimeout);
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
- (void)mouseDragged:(NSEvent *)event
|
|
166
183
|
{
|
|
167
184
|
[super mouseDragged:event];
|
|
168
185
|
|
|
186
|
+
[_gestureHandler.pointerTracker touchesMoved:[NSSet setWithObject:event] withEvent:event];
|
|
187
|
+
|
|
169
188
|
NSPoint currentPosition = [self locationInView:self.view];
|
|
170
189
|
double currentTime = CACurrentMediaTime();
|
|
171
190
|
|
|
@@ -180,16 +199,37 @@
|
|
|
180
199
|
[self tryActivate:velocityVector];
|
|
181
200
|
}
|
|
182
201
|
|
|
202
|
+
- (void)cancelMaxDurationTimeout
|
|
203
|
+
{
|
|
204
|
+
if (maxDurationTimeout != nil) {
|
|
205
|
+
dispatch_block_cancel(maxDurationTimeout);
|
|
206
|
+
maxDurationTimeout = nil;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
183
210
|
- (void)mouseUp:(NSEvent *)event
|
|
184
211
|
{
|
|
185
212
|
[super mouseUp:event];
|
|
186
213
|
|
|
187
|
-
|
|
214
|
+
[_gestureHandler.pointerTracker touchesEnded:[NSSet setWithObject:event] withEvent:event];
|
|
215
|
+
|
|
216
|
+
[self cancelMaxDurationTimeout];
|
|
188
217
|
|
|
189
218
|
self.state =
|
|
190
219
|
self.state == NSGestureRecognizerStateChanged ? NSGestureRecognizerStateEnded : NSGestureRecognizerStateFailed;
|
|
191
220
|
}
|
|
192
221
|
|
|
222
|
+
- (void)reset
|
|
223
|
+
{
|
|
224
|
+
[self triggerActionFromReset];
|
|
225
|
+
[_gestureHandler.pointerTracker reset];
|
|
226
|
+
// The gesture may end without a mouse-up (view unmount, cancellation) — a still-scheduled
|
|
227
|
+
// timeout would fire later and set the state to Failed during the next gesture.
|
|
228
|
+
[self cancelMaxDurationTimeout];
|
|
229
|
+
[super reset];
|
|
230
|
+
[_gestureHandler reset];
|
|
231
|
+
}
|
|
232
|
+
|
|
193
233
|
- (void)tryActivate:(Vector *)velocityVector
|
|
194
234
|
{
|
|
195
235
|
bool isAligned = NO;
|
|
@@ -132,8 +132,9 @@ API_AVAILABLE(ios(13.4))
|
|
|
132
132
|
{
|
|
133
133
|
#if CHECK_TARGET(13_4)
|
|
134
134
|
if (@available(iOS 13.4, *)) {
|
|
135
|
-
[super unbindFromView]
|
|
135
|
+
// Remove the interaction before [super unbindFromView] detaches the recognizer and nils recognizer.view.
|
|
136
136
|
[self.recognizer.view removeInteraction:_pointerInteraction];
|
|
137
|
+
[super unbindFromView];
|
|
137
138
|
}
|
|
138
139
|
#endif
|
|
139
140
|
}
|
|
@@ -218,33 +219,30 @@ API_AVAILABLE(ios(13.4))
|
|
|
218
219
|
_view = nil;
|
|
219
220
|
}
|
|
220
221
|
|
|
222
|
+
- (RNGestureHandlerEventExtraData *)extraDataForEvent:(NSEvent *)event
|
|
223
|
+
{
|
|
224
|
+
CGPoint windowLocation = [event locationInWindow];
|
|
225
|
+
CGPoint relativePos = [_view convertPoint:windowLocation fromView:nil];
|
|
226
|
+
CGPoint absolutePos = [_view.window.contentView convertPoint:windowLocation fromView:nil];
|
|
227
|
+
|
|
228
|
+
return [RNGestureHandlerEventExtraData forPosition:relativePos
|
|
229
|
+
withAbsolutePosition:absolutePos
|
|
230
|
+
withNumberOfTouches:1
|
|
231
|
+
withPointerType:_pointerType];
|
|
232
|
+
}
|
|
233
|
+
|
|
221
234
|
- (void)mouseEntered:(NSEvent *)event
|
|
222
235
|
{
|
|
223
|
-
[self
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
- (void)mouseExited:(NSEvent *)theEvent
|
|
236
|
-
{
|
|
237
|
-
[self sendEventsInState:RNGestureHandlerStateEnd
|
|
238
|
-
forViewWithTag:_view.reactTag
|
|
239
|
-
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO
|
|
240
|
-
withNumberOfTouches:1
|
|
241
|
-
withPointerType:_pointerType]];
|
|
242
|
-
|
|
243
|
-
[self sendEventsInState:RNGestureHandlerStateUndetermined
|
|
244
|
-
forViewWithTag:_view.reactTag
|
|
245
|
-
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO
|
|
246
|
-
withNumberOfTouches:1
|
|
247
|
-
withPointerType:_pointerType]];
|
|
236
|
+
RNGestureHandlerEventExtraData *extraData = [self extraDataForEvent:event];
|
|
237
|
+
[self sendEventsInState:RNGestureHandlerStateBegan forViewWithTag:_view.reactTag withExtraData:extraData];
|
|
238
|
+
[self sendEventsInState:RNGestureHandlerStateActive forViewWithTag:_view.reactTag withExtraData:extraData];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
- (void)mouseExited:(NSEvent *)event
|
|
242
|
+
{
|
|
243
|
+
RNGestureHandlerEventExtraData *extraData = [self extraDataForEvent:event];
|
|
244
|
+
[self sendEventsInState:RNGestureHandlerStateEnd forViewWithTag:_view.reactTag withExtraData:extraData];
|
|
245
|
+
[self sendEventsInState:RNGestureHandlerStateUndetermined forViewWithTag:_view.reactTag withExtraData:extraData];
|
|
248
246
|
}
|
|
249
247
|
|
|
250
248
|
@end
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
|
|
43
43
|
@implementation RNBetterPanGestureRecognizer {
|
|
44
44
|
__weak RNGestureHandler *_gestureHandler;
|
|
45
|
-
#if
|
|
45
|
+
#if TARGET_OS_OSX
|
|
46
|
+
BOOL _blockAutomaticActivation;
|
|
47
|
+
#else
|
|
46
48
|
NSUInteger _realMinimumNumberOfTouches;
|
|
47
49
|
#endif
|
|
48
50
|
BOOL _hasCustomActivationCriteria;
|
|
@@ -114,6 +116,9 @@
|
|
|
114
116
|
|
|
115
117
|
- (void)activateAfterLongPress
|
|
116
118
|
{
|
|
119
|
+
#if TARGET_OS_OSX
|
|
120
|
+
_blockAutomaticActivation = NO;
|
|
121
|
+
#endif
|
|
117
122
|
self.state = UIGestureRecognizerStateBegan;
|
|
118
123
|
// Send event in ACTIVE state because UIGestureRecognizerStateBegan is mapped to RNGestureHandlerStateBegan
|
|
119
124
|
[_gestureHandler handleGesture:self inState:RNGestureHandlerStateActive];
|
|
@@ -139,6 +144,11 @@
|
|
|
139
144
|
#endif
|
|
140
145
|
|
|
141
146
|
#if TARGET_OS_OSX
|
|
147
|
+
// NSPanGestureRecognizer transitions to the Began state on mouse-down, without any
|
|
148
|
+
// built-in movement hysteresis. To honor the custom activation criteria (minDist,
|
|
149
|
+
// activeOffsets, minVelocity) we hold the recognizer in the Possible state until
|
|
150
|
+
// they are met in interactionsMoved.
|
|
151
|
+
_blockAutomaticActivation = _hasCustomActivationCriteria;
|
|
142
152
|
[super mouseDown:event];
|
|
143
153
|
#else
|
|
144
154
|
[super touchesBegan:touches withEvent:event];
|
|
@@ -176,7 +186,14 @@
|
|
|
176
186
|
}
|
|
177
187
|
}
|
|
178
188
|
|
|
179
|
-
#if
|
|
189
|
+
#if TARGET_OS_OSX
|
|
190
|
+
if (_hasCustomActivationCriteria && self.state == UIGestureRecognizerStatePossible &&
|
|
191
|
+
[self shouldActivateUnderCustomCriteria]) {
|
|
192
|
+
_blockAutomaticActivation = NO;
|
|
193
|
+
self.state = UIGestureRecognizerStateBegan;
|
|
194
|
+
[self setTranslation:CGPointMake(0, 0) inView:self.view];
|
|
195
|
+
}
|
|
196
|
+
#elif !TARGET_OS_TV
|
|
180
197
|
if (_hasCustomActivationCriteria && self.state == UIGestureRecognizerStatePossible &&
|
|
181
198
|
[self shouldActivateUnderCustomCriteria]) {
|
|
182
199
|
super.minimumNumberOfTouches = _realMinimumNumberOfTouches;
|
|
@@ -209,6 +226,23 @@
|
|
|
209
226
|
|
|
210
227
|
#if TARGET_OS_OSX
|
|
211
228
|
|
|
229
|
+
- (void)setState:(NSGestureRecognizerState)state
|
|
230
|
+
{
|
|
231
|
+
if (_blockAutomaticActivation) {
|
|
232
|
+
if (state == NSGestureRecognizerStateBegan || state == NSGestureRecognizerStateChanged) {
|
|
233
|
+
// Hold the recognizer in the Possible state until the custom activation criteria
|
|
234
|
+
// are met — the superclass keeps tracking the mouse regardless, so translation
|
|
235
|
+
// and velocity stay valid for the criteria checks.
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (state == NSGestureRecognizerStateEnded) {
|
|
239
|
+
// Mouse released before the activation criteria were met — the gesture failed.
|
|
240
|
+
state = NSGestureRecognizerStateFailed;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
[super setState:state];
|
|
244
|
+
}
|
|
245
|
+
|
|
212
246
|
- (void)mouseDown:(NSEvent *)event
|
|
213
247
|
{
|
|
214
248
|
[_gestureHandler setCurrentPointerTypeToMouse];
|
|
@@ -265,6 +299,9 @@
|
|
|
265
299
|
[_gestureHandler.pointerTracker reset];
|
|
266
300
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(activateAfterLongPress) object:nil];
|
|
267
301
|
self.enabled = YES;
|
|
302
|
+
#if TARGET_OS_OSX
|
|
303
|
+
_blockAutomaticActivation = NO;
|
|
304
|
+
#endif
|
|
268
305
|
[super reset];
|
|
269
306
|
[_gestureHandler reset];
|
|
270
307
|
|
|
@@ -333,10 +370,10 @@
|
|
|
333
370
|
}
|
|
334
371
|
|
|
335
372
|
CGPoint velocity = [self velocityInView:self.view];
|
|
336
|
-
if (
|
|
373
|
+
if (TEST_ABS_MIN_IF_NOT_NAN(velocity.x, _minVelocityX)) {
|
|
337
374
|
return YES;
|
|
338
375
|
}
|
|
339
|
-
if (
|
|
376
|
+
if (TEST_ABS_MIN_IF_NOT_NAN(velocity.y, _minVelocityY)) {
|
|
340
377
|
return YES;
|
|
341
378
|
}
|
|
342
379
|
if (TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ(velocity), _minVelocitySq)) {
|
|
@@ -405,9 +442,9 @@
|
|
|
405
442
|
|
|
406
443
|
#if !TARGET_OS_OSX && !TARGET_OS_TV && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130400
|
|
407
444
|
if (@available(iOS 13.4, *)) {
|
|
408
|
-
|
|
409
|
-
if (enableTrackpadTwoFingerGesture) {
|
|
410
|
-
recognizer.allowedScrollTypesMask = UIScrollTypeMaskAll;
|
|
445
|
+
id enableTrackpadTwoFingerGesture = config[@"enableTrackpadTwoFingerGesture"];
|
|
446
|
+
if (enableTrackpadTwoFingerGesture != nil) {
|
|
447
|
+
recognizer.allowedScrollTypesMask = [RCTConvert BOOL:enableTrackpadTwoFingerGesture] ? UIScrollTypeMaskAll : 0;
|
|
411
448
|
}
|
|
412
449
|
}
|
|
413
450
|
|
|
@@ -38,6 +38,12 @@
|
|
|
38
38
|
NSUInteger _tapsSoFar;
|
|
39
39
|
CGPoint _initPosition;
|
|
40
40
|
NSInteger _maxNumberOfTouches;
|
|
41
|
+
// Pending `cancel` invocations scheduled via dispatch_after. We use dispatch blocks instead of
|
|
42
|
+
// performSelector:afterDelay: because the latter schedules its timer in NSDefaultRunLoopMode only,
|
|
43
|
+
// which means it is starved while a sibling UIScrollView keeps the run loop in UITrackingRunLoopMode
|
|
44
|
+
// (during a drag or momentum deceleration). dispatch_after fires regardless of run loop mode, so the
|
|
45
|
+
// tap can still fail/finalize on time while a list is scrolling. See issue #3471.
|
|
46
|
+
NSMutableArray<dispatch_block_t> *_pendingCancellations;
|
|
41
47
|
}
|
|
42
48
|
|
|
43
49
|
static const NSUInteger defaultNumberOfTaps = 1;
|
|
@@ -57,10 +63,33 @@ static const NSTimeInterval defaultMaxDuration = 0.5;
|
|
|
57
63
|
_maxDeltaX = NAN;
|
|
58
64
|
_maxDeltaY = NAN;
|
|
59
65
|
_maxDistSq = NAN;
|
|
66
|
+
_pendingCancellations = [NSMutableArray array];
|
|
60
67
|
}
|
|
61
68
|
return self;
|
|
62
69
|
}
|
|
63
70
|
|
|
71
|
+
- (void)scheduleCancelAfterDelay:(NSTimeInterval)delay
|
|
72
|
+
{
|
|
73
|
+
__weak typeof(self) weakSelf = self;
|
|
74
|
+
|
|
75
|
+
dispatch_block_t block = dispatch_block_create(0, ^{
|
|
76
|
+
[weakSelf cancel];
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
[_pendingCancellations addObject:block];
|
|
80
|
+
|
|
81
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), block);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
- (void)cancelPendingCancellations
|
|
85
|
+
{
|
|
86
|
+
for (dispatch_block_t block in _pendingCancellations) {
|
|
87
|
+
dispatch_block_cancel(block);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
[_pendingCancellations removeAllObjects];
|
|
91
|
+
}
|
|
92
|
+
|
|
64
93
|
- (void)triggerAction
|
|
65
94
|
{
|
|
66
95
|
[_gestureHandler handleGesture:self fromReset:NO];
|
|
@@ -93,14 +122,14 @@ static const NSTimeInterval defaultMaxDuration = 0.5;
|
|
|
93
122
|
}
|
|
94
123
|
_tapsSoFar++;
|
|
95
124
|
if (_tapsSoFar) {
|
|
96
|
-
[
|
|
125
|
+
[self cancelPendingCancellations];
|
|
97
126
|
}
|
|
98
127
|
NSInteger numberOfTouches = [touches count];
|
|
99
128
|
if (numberOfTouches > _maxNumberOfTouches) {
|
|
100
129
|
_maxNumberOfTouches = numberOfTouches;
|
|
101
130
|
}
|
|
102
131
|
if (!isnan(_maxDuration)) {
|
|
103
|
-
[self
|
|
132
|
+
[self scheduleCancelAfterDelay:_maxDuration];
|
|
104
133
|
}
|
|
105
134
|
self.state = UIGestureRecognizerStatePossible;
|
|
106
135
|
[self triggerAction];
|
|
@@ -132,10 +161,12 @@ static const NSTimeInterval defaultMaxDuration = 0.5;
|
|
|
132
161
|
{
|
|
133
162
|
[_gestureHandler.pointerTracker touchesEnded:touches withEvent:event];
|
|
134
163
|
|
|
164
|
+
[self cancelPendingCancellations];
|
|
165
|
+
|
|
135
166
|
if (_numberOfTaps == _tapsSoFar && _maxNumberOfTouches >= _minPointers) {
|
|
136
167
|
self.state = UIGestureRecognizerStateEnded;
|
|
137
168
|
} else {
|
|
138
|
-
[self
|
|
169
|
+
[self scheduleCancelAfterDelay:_maxDelay];
|
|
139
170
|
}
|
|
140
171
|
}
|
|
141
172
|
|
|
@@ -250,7 +281,7 @@ static const NSTimeInterval defaultMaxDuration = 0.5;
|
|
|
250
281
|
|
|
251
282
|
[_gestureHandler.pointerTracker reset];
|
|
252
283
|
|
|
253
|
-
[
|
|
284
|
+
[self cancelPendingCancellations];
|
|
254
285
|
_tapsSoFar = 0;
|
|
255
286
|
_maxNumberOfTouches = 0;
|
|
256
287
|
self.enabled = YES;
|
package/apple/RNGHUIKit.h
CHANGED
|
@@ -6,11 +6,11 @@ typedef UIView RNGHUIView;
|
|
|
6
6
|
typedef UITouch RNGHUITouch;
|
|
7
7
|
typedef UIScrollView RNGHUIScrollView;
|
|
8
8
|
|
|
9
|
-
#define RNGHGestureRecognizerStateFailed UIGestureRecognizerStateFailed
|
|
10
|
-
#define RNGHGestureRecognizerStatePossible UIGestureRecognizerStatePossible
|
|
11
|
-
#define RNGHGestureRecognizerStateCancelled UIGestureRecognizerStateCancelled
|
|
12
|
-
#define RNGHGestureRecognizerStateBegan UIGestureRecognizerStateBegan
|
|
13
|
-
#define RNGHGestureRecognizerStateEnded UIGestureRecognizerStateEnded
|
|
9
|
+
#define RNGHGestureRecognizerStateFailed UIGestureRecognizerStateFailed
|
|
10
|
+
#define RNGHGestureRecognizerStatePossible UIGestureRecognizerStatePossible
|
|
11
|
+
#define RNGHGestureRecognizerStateCancelled UIGestureRecognizerStateCancelled
|
|
12
|
+
#define RNGHGestureRecognizerStateBegan UIGestureRecognizerStateBegan
|
|
13
|
+
#define RNGHGestureRecognizerStateEnded UIGestureRecognizerStateEnded
|
|
14
14
|
|
|
15
15
|
#else // TARGET_OS_OSX [
|
|
16
16
|
|
|
@@ -20,10 +20,10 @@ typedef RCTUIView RNGHUIView;
|
|
|
20
20
|
typedef RCTUITouch RNGHUITouch;
|
|
21
21
|
typedef NSScrollView RNGHUIScrollView;
|
|
22
22
|
|
|
23
|
-
#define RNGHGestureRecognizerStateFailed NSGestureRecognizerStateFailed
|
|
24
|
-
#define RNGHGestureRecognizerStatePossible NSGestureRecognizerStatePossible
|
|
25
|
-
#define RNGHGestureRecognizerStateCancelled NSGestureRecognizerStateCancelled
|
|
26
|
-
#define RNGHGestureRecognizerStateBegan NSGestureRecognizerStateBegan
|
|
27
|
-
#define RNGHGestureRecognizerStateEnded NSGestureRecognizerStateEnded
|
|
23
|
+
#define RNGHGestureRecognizerStateFailed NSGestureRecognizerStateFailed
|
|
24
|
+
#define RNGHGestureRecognizerStatePossible NSGestureRecognizerStatePossible
|
|
25
|
+
#define RNGHGestureRecognizerStateCancelled NSGestureRecognizerStateCancelled
|
|
26
|
+
#define RNGHGestureRecognizerStateBegan NSGestureRecognizerStateBegan
|
|
27
|
+
#define RNGHGestureRecognizerStateEnded NSGestureRecognizerStateEnded
|
|
28
28
|
|
|
29
29
|
#endif // ] TARGET_OS_OSX
|
package/apple/RNGestureHandler.h
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
#define TEST_MIN_IF_NOT_NAN(value, limit) \
|
|
15
15
|
(!isnan(limit) && ((limit < 0 && value <= limit) || (limit >= 0 && value >= limit)))
|
|
16
16
|
|
|
17
|
+
#define TEST_ABS_MIN_IF_NOT_NAN(value, limit) (!isnan(limit) && fabs(value) >= fabs(limit))
|
|
18
|
+
|
|
17
19
|
#define TEST_MAX_IF_NOT_NAN(value, max) (!isnan(max) && ((max < 0 && value < max) || (max >= 0 && value > max)))
|
|
18
20
|
|
|
19
21
|
#define APPLY_PROP(recognizer, config, type, prop, propName) \
|
|
@@ -253,6 +253,24 @@ static NSHashTable<RNGestureHandler *> *allGestureHandlers;
|
|
|
253
253
|
|
|
254
254
|
- (void)unbindFromView
|
|
255
255
|
{
|
|
256
|
+
// If the gesture is still in flight - e.g. the view is being unmounted mid-gesture - deliver
|
|
257
|
+
// the final event now, while the recognizer is still attached and the target view is known.
|
|
258
|
+
// Otherwise the onBegin/onFinalize and onActivate/onDeactivate guarantees would be broken
|
|
259
|
+
// and `_lastState` would never be cleared by `reset`.
|
|
260
|
+
if (self.recognizer.view != nil &&
|
|
261
|
+
(_lastState == RNGestureHandlerStateBegan || _lastState == RNGestureHandlerStateActive)) {
|
|
262
|
+
if ([self eventTagForRecognizer:self.recognizer] != nil) {
|
|
263
|
+
[self handleGesture:self.recognizer
|
|
264
|
+
inState:_lastState == RNGestureHandlerStateActive ? RNGestureHandlerStateCancelled
|
|
265
|
+
: RNGestureHandlerStateFailed];
|
|
266
|
+
} else {
|
|
267
|
+
// The event has no tag to be dispatched with, so it cannot be delivered on any path - reset
|
|
268
|
+
// the bookkeeping so the handler doesn't stay in-flight forever.
|
|
269
|
+
_lastState = RNGestureHandlerStateUndetermined;
|
|
270
|
+
_state = RNGestureHandlerStateBegan;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
256
274
|
[self.recognizer.view removeGestureRecognizer:self.recognizer];
|
|
257
275
|
self.recognizer.delegate = nil;
|
|
258
276
|
self.viewTag = nil;
|
|
@@ -314,21 +332,38 @@ static NSHashTable<RNGestureHandler *> *allGestureHandlers;
|
|
|
314
332
|
//
|
|
315
333
|
// While this solution is not great, we decided to check whether sending events was triggered from `reset` method.
|
|
316
334
|
// This way we can detect double Began mapping by checking previous sent state and current state of recognizer.
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
335
|
+
//
|
|
336
|
+
// The same applies to gestures interrupted mid-flight, e.g. when the view is unmounted during an active
|
|
337
|
+
// gesture the recognizer may be reset without its cancel action ever firing.
|
|
338
|
+
// If the last sent state is not final, synthesize the missing final event so that the
|
|
339
|
+
// `onBegin`/`onFinalize` and `onActivate`/`onDeactivate` guarantees hold.
|
|
340
|
+
if (fromReset && self.recognizer.state == UIGestureRecognizerStatePossible) {
|
|
341
|
+
if (_lastState == RNGestureHandlerStateBegan) {
|
|
342
|
+
_state = RNGestureHandlerStateFailed;
|
|
343
|
+
} else if (_lastState == RNGestureHandlerStateActive) {
|
|
344
|
+
_state = RNGestureHandlerStateCancelled;
|
|
345
|
+
} else {
|
|
346
|
+
// The final event was already delivered; mapping Possible to Began here would emit a stray
|
|
347
|
+
// BEGAN event after the gesture has finished.
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
320
350
|
}
|
|
321
351
|
|
|
322
352
|
[self handleGesture:recognizer inState:_state];
|
|
323
353
|
}
|
|
324
354
|
|
|
355
|
+
- (nullable NSNumber *)eventTagForRecognizer:(UIGestureRecognizer *)recognizer
|
|
356
|
+
{
|
|
357
|
+
return [self chooseViewForInteraction:recognizer].reactTag;
|
|
358
|
+
}
|
|
359
|
+
|
|
325
360
|
- (void)handleGesture:(UIGestureRecognizer *)recognizer inState:(RNGestureHandlerState)state
|
|
326
361
|
{
|
|
327
362
|
_state = state;
|
|
328
363
|
RNGestureHandlerEventExtraData *eventData = [self eventExtraData:recognizer];
|
|
329
|
-
|
|
364
|
+
NSNumber *tag = [self eventTagForRecognizer:recognizer];
|
|
330
365
|
|
|
331
|
-
[self sendEventsInState:self.state forViewWithTag:
|
|
366
|
+
[self sendEventsInState:self.state forViewWithTag:tag withExtraData:eventData];
|
|
332
367
|
}
|
|
333
368
|
|
|
334
369
|
- (void)sendEventsInState:(RNGestureHandlerState)state
|
|
@@ -636,7 +671,13 @@ static NSHashTable<RNGestureHandler *> *allGestureHandlers;
|
|
|
636
671
|
// might be called after some pointers are down, and after state manipulation by the user.
|
|
637
672
|
// Pointer tracker calls this method when it resets, and in that case it no longer tracks
|
|
638
673
|
// any pointers, thus entering this if
|
|
639
|
-
|
|
674
|
+
//
|
|
675
|
+
// Also do not clear _lastState while the gesture is in flight (BEGAN/ACTIVE) - the final
|
|
676
|
+
// state-change event hasn't been dispatched yet. When the view is removed mid-gesture,
|
|
677
|
+
// the pointer tracker resets before the recognizer's cancel action fires; clearing _lastState
|
|
678
|
+
// here would corrupt the prevState of the outgoing CANCELLED event and break the onActivate/onDeactivate guarantee.
|
|
679
|
+
if ((!_needsPointerData || _pointerTracker.trackedPointersCount == 0) && _lastState != RNGestureHandlerStateBegan &&
|
|
680
|
+
_lastState != RNGestureHandlerStateActive) {
|
|
640
681
|
_lastState = RNGestureHandlerStateUndetermined;
|
|
641
682
|
_state = RNGestureHandlerStateBegan;
|
|
642
683
|
}
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
{
|
|
63
63
|
if ([view isKindOfClass:[RNGestureHandlerButton class]]) {
|
|
64
64
|
RNGestureHandlerButton *button = (RNGestureHandlerButton *)view;
|
|
65
|
-
return button.userEnabled
|
|
65
|
+
return button.userEnabled && button.pointerEvents != RNGestureHandlerPointerEventsBoxNone &&
|
|
66
|
+
button.pointerEvents != RNGestureHandlerPointerEventsNone;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
// Certain subviews such as RCTViewComponentView have been observed to have disabled
|
|
@@ -105,7 +106,8 @@
|
|
|
105
106
|
if (!subview.isHidden && subview.alpha > 0) {
|
|
106
107
|
CGPoint convertedPoint = [subview convertPoint:point fromView:self];
|
|
107
108
|
UIView *hitView = [subview hitTest:convertedPoint withEvent:event];
|
|
108
|
-
if (hitView != nil &&
|
|
109
|
+
if (hitView != nil &&
|
|
110
|
+
([hitView isKindOfClass:[RNGestureHandlerButton class]] || [self shouldHandleTouch:hitView])) {
|
|
109
111
|
return hitView;
|
|
110
112
|
}
|
|
111
113
|
}
|
|
@@ -118,7 +120,7 @@
|
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
RNGHUIView *inner = [super hitTest:point withEvent:event];
|
|
121
|
-
while (inner && ![self shouldHandleTouch:inner]) {
|
|
123
|
+
while (inner && inner != self && ![self shouldHandleTouch:inner]) {
|
|
122
124
|
inner = inner.superview;
|
|
123
125
|
}
|
|
124
126
|
return inner;
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
#import <React/RCTEventDispatcherProtocol.h>
|
|
5
5
|
#import <React/RCTLog.h>
|
|
6
6
|
#import <React/RCTModalHostViewController.h>
|
|
7
|
-
#import <React/RCTRootContentView.h>
|
|
8
7
|
#import <React/RCTRootView.h>
|
|
9
8
|
#import <React/RCTUIManager.h>
|
|
10
9
|
#import <React/RCTViewManager.h>
|
|
@@ -275,20 +274,50 @@ constexpr int NEW_ARCH_NUMBER_OF_ATTACH_RETRIES = 25;
|
|
|
275
274
|
|
|
276
275
|
#pragma mark Root Views Management
|
|
277
276
|
|
|
277
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
278
|
+
#if !TARGET_OS_OSX
|
|
279
|
+
static BOOL RNGHIsScreensTouchHandlerHost(RNGHUIView *view)
|
|
280
|
+
{
|
|
281
|
+
static Class fullWindowOverlayContainerClass;
|
|
282
|
+
static Class screenViewClass;
|
|
283
|
+
static SEL isModalSelector;
|
|
284
|
+
static dispatch_once_t onceToken;
|
|
285
|
+
dispatch_once(&onceToken, ^{
|
|
286
|
+
fullWindowOverlayContainerClass = NSClassFromString(@"RNSFullWindowOverlayContainer");
|
|
287
|
+
screenViewClass = NSClassFromString(@"RNSScreenView");
|
|
288
|
+
isModalSelector = NSSelectorFromString(@"isModal");
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
if (fullWindowOverlayContainerClass != nil && [view isKindOfClass:fullWindowOverlayContainerClass]) {
|
|
292
|
+
return YES;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (screenViewClass != nil && [view isKindOfClass:screenViewClass]) {
|
|
296
|
+
// For now we consider only modals
|
|
297
|
+
return [view respondsToSelector:isModalSelector] && [[view valueForKey:@"isModal"] boolValue];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return NO;
|
|
301
|
+
}
|
|
302
|
+
#endif // !TARGET_OS_OSX
|
|
303
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
304
|
+
|
|
278
305
|
- (void)registerViewWithGestureRecognizerAttachedIfNeeded:(RNGHUIView *)childView
|
|
306
|
+
{
|
|
307
|
+
[self registerViewWithGestureRecognizerAttachedIfNeeded:childView isRetry:NO];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
- (void)registerViewWithGestureRecognizerAttachedIfNeeded:(RNGHUIView *)childView isRetry:(BOOL)isRetry
|
|
279
311
|
{
|
|
280
312
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
281
313
|
RNGHUIView *touchHandlerView = childView;
|
|
282
314
|
|
|
283
315
|
#if !TARGET_OS_OSX
|
|
284
|
-
Class fullWindowOverlayContainerClass = NSClassFromString(@"RNSFullWindowOverlayContainer");
|
|
285
|
-
|
|
286
316
|
if ([[childView reactViewController] isKindOfClass:[RCTFabricModalHostViewController class]]) {
|
|
287
317
|
touchHandlerView = [childView reactViewController].view;
|
|
288
318
|
} else {
|
|
289
|
-
while (
|
|
290
|
-
|
|
291
|
-
(fullWindowOverlayContainerClass == nil || ![touchHandlerView isKindOfClass:fullWindowOverlayContainerClass])) {
|
|
319
|
+
while (touchHandlerView != nil && ![touchHandlerView isKindOfClass:[RCTSurfaceView class]] &&
|
|
320
|
+
!RNGHIsScreensTouchHandlerHost(touchHandlerView)) {
|
|
292
321
|
touchHandlerView = touchHandlerView.superview;
|
|
293
322
|
}
|
|
294
323
|
}
|
|
@@ -324,6 +353,19 @@ constexpr int NEW_ARCH_NUMBER_OF_ATTACH_RETRIES = 25;
|
|
|
324
353
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
325
354
|
|
|
326
355
|
if (touchHandlerView == nil) {
|
|
356
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
357
|
+
#if !TARGET_OS_OSX
|
|
358
|
+
// Handlers are attached while the mounting transaction is still in progress — the view's
|
|
359
|
+
// ancestor chain may not be assembled yet (Fabric connects subtrees children-first), in
|
|
360
|
+
// which case the walk above dead-ends before reaching any touch-handling root. Retry once
|
|
361
|
+
// on the next run loop turn, when mounting has finished and the hierarchy is connected.
|
|
362
|
+
if (!isRetry) {
|
|
363
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
364
|
+
[self registerViewWithGestureRecognizerAttachedIfNeeded:childView isRetry:YES];
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
#endif // !TARGET_OS_OSX
|
|
368
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
327
369
|
return;
|
|
328
370
|
}
|
|
329
371
|
|
|
@@ -382,6 +424,21 @@ constexpr int NEW_ARCH_NUMBER_OF_ATTACH_RETRIES = 25;
|
|
|
382
424
|
break;
|
|
383
425
|
}
|
|
384
426
|
}
|
|
427
|
+
|
|
428
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
429
|
+
#if !TARGET_OS_OSX
|
|
430
|
+
if (touchHandler == nil && [viewWithTouchHandler respondsToSelector:NSSelectorFromString(@"touchHandler")]) {
|
|
431
|
+
// An RNSScreenView may not have the touch handler attached directly (e.g. touches on it are
|
|
432
|
+
// still driven by an ancestor's touch handler) — ask react-native-screens for the one
|
|
433
|
+
// responsible for this screen.
|
|
434
|
+
id screenTouchHandler = [viewWithTouchHandler valueForKey:@"touchHandler"];
|
|
435
|
+
if ([screenTouchHandler isKindOfClass:[RCTSurfaceTouchHandler class]]) {
|
|
436
|
+
touchHandler = screenTouchHandler;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
#endif // !TARGET_OS_OSX
|
|
440
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
441
|
+
|
|
385
442
|
[touchHandler setEnabled:NO];
|
|
386
443
|
[touchHandler setEnabled:YES];
|
|
387
444
|
}
|