react-native-gesture-handler 2.10.0 → 2.10.1

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.
@@ -16,6 +16,7 @@
16
16
 
17
17
  #ifdef RCT_NEW_ARCH_ENABLED
18
18
  #import <React/RCTSurfaceTouchHandler.h>
19
+ #import <React/RCTSurfaceView.h>
19
20
  #import <React/RCTViewComponentView.h>
20
21
  #else
21
22
  #import <React/RCTTouchHandler.h>
@@ -37,6 +38,8 @@
37
38
  RCTDefaultLogFunction( \
38
39
  RCTLogLevelInfo, RCTLogSourceNative, @(__FILE__), @(__LINE__), [NSString stringWithFormat:__VA_ARGS__])
39
40
 
41
+ constexpr int NEW_ARCH_NUMBER_OF_ATTACH_RETRIES = 25;
42
+
40
43
  @interface RNGestureHandlerManager () <RNGestureHandlerEventEmitter, RNRootViewGestureRecognizerDelegate>
41
44
 
42
45
  @end
@@ -45,6 +48,7 @@
45
48
  RNGestureHandlerRegistry *_registry;
46
49
  RCTUIManager *_uiManager;
47
50
  NSHashTable<RNRootViewGestureRecognizer *> *_rootViewGestureRecognizers;
51
+ NSMutableDictionary<NSNumber *, NSNumber *> *_attachRetryCounter;
48
52
  RCTEventDispatcher *_eventDispatcher;
49
53
  id _reanimatedModule;
50
54
  }
@@ -56,6 +60,7 @@
56
60
  _eventDispatcher = eventDispatcher;
57
61
  _registry = [RNGestureHandlerRegistry new];
58
62
  _rootViewGestureRecognizers = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
63
+ _attachRetryCounter = [[NSMutableDictionary alloc] init];
59
64
  _reanimatedModule = nil;
60
65
  }
61
66
  return self;
@@ -100,12 +105,39 @@
100
105
  UIView *view = [_uiManager viewForReactTag:viewTag];
101
106
 
102
107
  #ifdef RCT_NEW_ARCH_ENABLED
103
- if (view == nil) {
104
- // Happens when the view with given tag has been flattened.
105
- // We cannot attach gesture handler to a non-existent view.
108
+ if (view == nil || view.superview == nil) {
109
+ // There are a few reasons we could end up here:
110
+ // - the native view corresponding to the viewtag hasn't yet been created
111
+ // - the native view has been created, but it's not attached to window
112
+ // - the native view will not exist because it got flattened
113
+ // In the first two cases we just want to wait until the view gets created or gets attached to its superview
114
+ // In the third case we don't want to do anything but we cannot easily distinguish it here, hece the abomination
115
+ // below
116
+ // TODO: would be great to have a better solution, although it might require migration to the shadow nodes from
117
+ // viewTags
118
+
119
+ NSNumber *counter = [_attachRetryCounter objectForKey:viewTag];
120
+ if (counter == nil) {
121
+ counter = @1;
122
+ } else {
123
+ counter = [NSNumber numberWithInt:counter.intValue + 1];
124
+ }
125
+
126
+ if (counter.intValue > NEW_ARCH_NUMBER_OF_ATTACH_RETRIES) {
127
+ [_attachRetryCounter removeObjectForKey:viewTag];
128
+ } else {
129
+ [_attachRetryCounter setObject:counter forKey:viewTag];
130
+
131
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
132
+ [self attachGestureHandler:handlerTag toViewWithTag:viewTag withActionType:actionType];
133
+ });
134
+ }
135
+
106
136
  return;
107
137
  }
108
138
 
139
+ [_attachRetryCounter removeObjectForKey:viewTag];
140
+
109
141
  // I think it should be moved to RNNativeViewHandler, but that would require
110
142
  // additional logic for setting contentView.reactTag, this works for now
111
143
  if ([view isKindOfClass:[RCTViewComponentView class]]) {
@@ -164,18 +196,26 @@
164
196
 
165
197
  - (void)registerViewWithGestureRecognizerAttachedIfNeeded:(UIView *)childView
166
198
  {
199
+ #ifdef RCT_NEW_ARCH_ENABLED
200
+ UIView *touchHandlerView = childView;
201
+
202
+ while (touchHandlerView != nil && ![touchHandlerView isKindOfClass:[RCTSurfaceView class]]) {
203
+ touchHandlerView = touchHandlerView.superview;
204
+ }
205
+ #else
167
206
  UIView *parent = childView;
168
207
  while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)])
169
208
  parent = parent.superview;
170
209
 
171
- // Many views can return the same touchHandler so we check if the one we want to register
172
- // is not already present in the set.
173
210
  UIView *touchHandlerView = [[parent performSelector:@selector(touchHandler)] view];
211
+ #endif // RCT_NEW_ARCH_ENABLED
174
212
 
175
213
  if (touchHandlerView == nil) {
176
214
  return;
177
215
  }
178
216
 
217
+ // Many views can return the same touchHandler so we check if the one we want to register
218
+ // is not already present in the set.
179
219
  for (UIGestureRecognizer *recognizer in touchHandlerView.gestureRecognizers) {
180
220
  if ([recognizer isKindOfClass:[RNRootViewGestureRecognizer class]]) {
181
221
  return;
@@ -208,10 +248,19 @@
208
248
  return;
209
249
 
210
250
  #ifdef RCT_NEW_ARCH_ENABLED
211
- RCTSurfaceTouchHandler *touchHandler = [viewWithTouchHandler performSelector:@selector(touchHandler)];
251
+ UIGestureRecognizer *touchHandler = nil;
252
+
253
+ // touchHandler (RCTSurfaceTouchHandler) is private in RCTFabricSurface so we have to do
254
+ // this little trick to get access to it
255
+ for (UIGestureRecognizer *recognizer in [viewWithTouchHandler gestureRecognizers]) {
256
+ if ([recognizer isKindOfClass:[RCTSurfaceTouchHandler class]]) {
257
+ touchHandler = recognizer;
258
+ break;
259
+ }
260
+ }
212
261
  #else
213
262
  RCTTouchHandler *touchHandler = [viewWithTouchHandler performSelector:@selector(touchHandler)];
214
- #endif
263
+ #endif // RCT_NEW_ARCH_ENABLED
215
264
  [touchHandler setEnabled:NO];
216
265
  [touchHandler setEnabled:YES];
217
266
  }
@@ -184,6 +184,9 @@ RCT_EXPORT_METHOD(handleClearJSResponder)
184
184
 
185
185
  RCT_EXPORT_METHOD(flushOperations)
186
186
  {
187
+ // On the new arch we rely on `flushOperations` for scheduling the operations on the UI thread.
188
+ // On the old arch we rely on `uiManagerWillPerformMounting`
189
+ #ifdef RCT_NEW_ARCH_ENABLED
187
190
  if (_operations.count == 0) {
188
191
  return;
189
192
  }
@@ -197,6 +200,7 @@ RCT_EXPORT_METHOD(flushOperations)
197
200
  operation(self->_manager);
198
201
  }
199
202
  }];
203
+ #endif // RCT_NEW_ARCH_ENABLED
200
204
  }
201
205
 
202
206
  - (void)setGestureState:(int)state forHandler:(int)handlerTag
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gesture-handler",
3
- "version": "2.10.0",
3
+ "version": "2.10.1",
4
4
  "description": "Experimental implementation of a new declarative API for gesture handling in react-native",
5
5
  "scripts": {
6
6
  "prepare": "bob build && husky install",