react-native-gesture-handler 2.18.0 → 2.19.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.
Files changed (141) hide show
  1. package/README.md +1 -0
  2. package/android/build.gradle +4 -17
  3. package/android/src/main/AndroidManifest.xml +1 -3
  4. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +21 -21
  5. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +2 -2
  6. package/android/src/main/java/com/swmansion/gesturehandler/core/HoverGestureHandler.kt +5 -0
  7. package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +80 -4
  8. package/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt +2 -1
  9. package/android/src/main/java/com/swmansion/gesturehandler/core/ScaleGestureDetector.java +10 -0
  10. package/android/src/main/java/com/swmansion/gesturehandler/core/Vector.kt +2 -2
  11. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +3 -0
  12. package/android/src/main/jni/cpp-adapter.cpp +2 -4
  13. package/apple/Handlers/RNFlingHandler.h +1 -0
  14. package/apple/Handlers/RNFlingHandler.m +153 -19
  15. package/apple/Handlers/RNHoverHandler.m +44 -2
  16. package/apple/Handlers/RNLongPressHandler.m +109 -20
  17. package/apple/Handlers/RNManualHandler.m +53 -29
  18. package/apple/Handlers/RNNativeViewHandler.mm +22 -15
  19. package/apple/RNGHUIKit.h +2 -0
  20. package/apple/RNGHVector.h +31 -0
  21. package/apple/RNGHVector.m +67 -0
  22. package/apple/RNGestureHandler.h +7 -0
  23. package/apple/{RNGestureHandler.m → RNGestureHandler.mm} +63 -1
  24. package/apple/RNGestureHandlerButtonComponentView.mm +6 -0
  25. package/apple/RNGestureHandlerDirection.h +25 -0
  26. package/apple/RNGestureHandlerModule.mm +2 -4
  27. package/lib/commonjs/PointerType.js +2 -1
  28. package/lib/commonjs/PointerType.js.map +1 -1
  29. package/lib/commonjs/components/Pressable/Pressable.js +67 -70
  30. package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
  31. package/lib/commonjs/components/Pressable/index.js +0 -8
  32. package/lib/commonjs/components/Pressable/index.js.map +1 -1
  33. package/lib/commonjs/components/ReanimatedSwipeable.js +60 -41
  34. package/lib/commonjs/components/ReanimatedSwipeable.js.map +1 -1
  35. package/lib/commonjs/components/Swipeable.js +5 -0
  36. package/lib/commonjs/components/Swipeable.js.map +1 -1
  37. package/lib/commonjs/handlers/LongPressGestureHandler.js +1 -1
  38. package/lib/commonjs/handlers/LongPressGestureHandler.js.map +1 -1
  39. package/lib/commonjs/handlers/gestures/GestureDetector/utils.js +1 -1
  40. package/lib/commonjs/handlers/gestures/GestureDetector/utils.js.map +1 -1
  41. package/lib/commonjs/handlers/gestures/longPressGesture.js +10 -0
  42. package/lib/commonjs/handlers/gestures/longPressGesture.js.map +1 -1
  43. package/lib/commonjs/mocks.js +16 -3
  44. package/lib/commonjs/mocks.js.map +1 -1
  45. package/lib/commonjs/utils.js +4 -0
  46. package/lib/commonjs/utils.js.map +1 -1
  47. package/lib/commonjs/web/constants.js +3 -3
  48. package/lib/commonjs/web/constants.js.map +1 -1
  49. package/lib/commonjs/web/handlers/GestureHandler.js +1 -0
  50. package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
  51. package/lib/commonjs/web/handlers/LongPressGestureHandler.js +43 -9
  52. package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
  53. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +14 -3
  54. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
  55. package/lib/commonjs/web/handlers/PanGestureHandler.js +4 -0
  56. package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
  57. package/lib/commonjs/web/interfaces.js.map +1 -1
  58. package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +55 -8
  59. package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
  60. package/lib/commonjs/web/tools/KeyboardEventManager.js +110 -0
  61. package/lib/commonjs/web/tools/KeyboardEventManager.js.map +1 -0
  62. package/lib/commonjs/web/tools/Vector.js +4 -2
  63. package/lib/commonjs/web/tools/Vector.js.map +1 -1
  64. package/lib/commonjs/web/utils.js +14 -13
  65. package/lib/commonjs/web/utils.js.map +1 -1
  66. package/lib/module/PointerType.js +2 -1
  67. package/lib/module/PointerType.js.map +1 -1
  68. package/lib/module/components/Pressable/Pressable.js +66 -70
  69. package/lib/module/components/Pressable/Pressable.js.map +1 -1
  70. package/lib/module/components/Pressable/index.js +0 -1
  71. package/lib/module/components/Pressable/index.js.map +1 -1
  72. package/lib/module/components/ReanimatedSwipeable.js +58 -37
  73. package/lib/module/components/ReanimatedSwipeable.js.map +1 -1
  74. package/lib/module/components/Swipeable.js +6 -0
  75. package/lib/module/components/Swipeable.js.map +1 -1
  76. package/lib/module/handlers/LongPressGestureHandler.js +1 -1
  77. package/lib/module/handlers/LongPressGestureHandler.js.map +1 -1
  78. package/lib/module/handlers/gestures/GestureDetector/utils.js +2 -2
  79. package/lib/module/handlers/gestures/GestureDetector/utils.js.map +1 -1
  80. package/lib/module/handlers/gestures/longPressGesture.js +10 -0
  81. package/lib/module/handlers/gestures/longPressGesture.js.map +1 -1
  82. package/lib/module/mocks.js +13 -3
  83. package/lib/module/mocks.js.map +1 -1
  84. package/lib/module/utils.js +1 -0
  85. package/lib/module/utils.js.map +1 -1
  86. package/lib/module/web/constants.js +1 -1
  87. package/lib/module/web/constants.js.map +1 -1
  88. package/lib/module/web/handlers/GestureHandler.js +1 -0
  89. package/lib/module/web/handlers/GestureHandler.js.map +1 -1
  90. package/lib/module/web/handlers/LongPressGestureHandler.js +43 -9
  91. package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
  92. package/lib/module/web/handlers/NativeViewGestureHandler.js +14 -3
  93. package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
  94. package/lib/module/web/handlers/PanGestureHandler.js +4 -0
  95. package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
  96. package/lib/module/web/interfaces.js.map +1 -1
  97. package/lib/module/web/tools/GestureHandlerWebDelegate.js +54 -8
  98. package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
  99. package/lib/module/web/tools/KeyboardEventManager.js +96 -0
  100. package/lib/module/web/tools/KeyboardEventManager.js.map +1 -0
  101. package/lib/module/web/tools/Vector.js +5 -3
  102. package/lib/module/web/tools/Vector.js.map +1 -1
  103. package/lib/module/web/utils.js +14 -13
  104. package/lib/module/web/utils.js.map +1 -1
  105. package/lib/typescript/PointerType.d.ts +2 -1
  106. package/lib/typescript/components/Pressable/index.d.ts +1 -1
  107. package/lib/typescript/components/Swipeable.d.ts +5 -0
  108. package/lib/typescript/handlers/LongPressGestureHandler.d.ts +5 -1
  109. package/lib/typescript/handlers/gestures/longPressGesture.d.ts +5 -0
  110. package/lib/typescript/mocks.d.ts +4 -3
  111. package/lib/typescript/utils.d.ts +1 -0
  112. package/lib/typescript/web/constants.d.ts +1 -1
  113. package/lib/typescript/web/handlers/GestureHandler.d.ts +1 -1
  114. package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts +3 -0
  115. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
  116. package/lib/typescript/web/interfaces.d.ts +1 -1
  117. package/lib/typescript/web/tools/GestureHandlerDelegate.d.ts +1 -0
  118. package/lib/typescript/web/tools/GestureHandlerWebDelegate.d.ts +6 -0
  119. package/lib/typescript/web/tools/KeyboardEventManager.d.ts +13 -0
  120. package/package.json +3 -3
  121. package/src/PointerType.ts +1 -0
  122. package/src/components/Pressable/Pressable.tsx +70 -50
  123. package/src/components/Pressable/index.ts +1 -1
  124. package/src/components/ReanimatedSwipeable.tsx +70 -47
  125. package/src/components/Swipeable.tsx +6 -0
  126. package/src/handlers/LongPressGestureHandler.ts +6 -0
  127. package/src/handlers/gestures/GestureDetector/utils.ts +2 -2
  128. package/src/handlers/gestures/longPressGesture.ts +9 -0
  129. package/src/{mocks.ts → mocks.tsx} +8 -3
  130. package/src/utils.ts +2 -0
  131. package/src/web/constants.ts +1 -1
  132. package/src/web/handlers/GestureHandler.ts +3 -1
  133. package/src/web/handlers/LongPressGestureHandler.ts +49 -10
  134. package/src/web/handlers/NativeViewGestureHandler.ts +14 -4
  135. package/src/web/handlers/PanGestureHandler.ts +4 -0
  136. package/src/web/interfaces.ts +1 -1
  137. package/src/web/tools/GestureHandlerDelegate.ts +1 -0
  138. package/src/web/tools/GestureHandlerWebDelegate.ts +67 -8
  139. package/src/web/tools/KeyboardEventManager.ts +91 -0
  140. package/src/web/tools/Vector.ts +4 -3
  141. package/src/web/utils.ts +15 -13
@@ -7,22 +7,37 @@
7
7
  //
8
8
 
9
9
  #import "RNLongPressHandler.h"
10
+ #import <React/RCTConvert.h>
10
11
 
11
12
  #if !TARGET_OS_OSX
12
13
 
13
14
  #import <UIKit/UIGestureRecognizerSubclass.h>
14
15
 
15
- #import <React/RCTConvert.h>
16
-
17
16
  @interface RNBetterLongPressGestureRecognizer : UILongPressGestureRecognizer {
17
+ #else
18
+ @interface RNBetterLongPressGestureRecognizer : NSGestureRecognizer {
19
+ dispatch_block_t block;
20
+ #endif
21
+
18
22
  CFTimeInterval startTime;
19
23
  CFTimeInterval previousTime;
20
24
  }
21
25
 
26
+ #if TARGET_OS_OSX
27
+ @property (nonatomic, assign) double minimumPressDuration;
28
+ @property (nonatomic, assign) double allowableMovement;
29
+ @property (nonatomic, assign) double numberOfTouchesRequired;
30
+ #endif
31
+
22
32
  - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler;
23
- - (void)handleGesture:(UIGestureRecognizer *)recognizer;
24
33
  - (NSUInteger)getDuration;
25
34
 
35
+ #if !TARGET_OS_OSX
36
+ - (void)handleGesture:(UIGestureRecognizer *)recognizer;
37
+ #else
38
+ - (void)handleGesture:(NSGestureRecognizer *)recognizer;
39
+ #endif
40
+
26
41
  @end
27
42
 
28
43
  @implementation RNBetterLongPressGestureRecognizer {
@@ -55,12 +70,16 @@
55
70
  return CGPointMake(currentPosition.x - _initPosition.x, currentPosition.y - _initPosition.y);
56
71
  }
57
72
 
73
+ #if !TARGET_OS_OSX
74
+
58
75
  - (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
59
76
  {
60
77
  [_gestureHandler setCurrentPointerType:event];
61
78
  [super touchesBegan:touches withEvent:event];
62
79
  [_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
63
80
 
81
+ self.state = UIGestureRecognizerStatePossible;
82
+
64
83
  _initPosition = [self locationInView:self.view];
65
84
  startTime = CACurrentMediaTime();
66
85
  [_gestureHandler reset];
@@ -72,10 +91,8 @@
72
91
  [super touchesMoved:touches withEvent:event];
73
92
  [_gestureHandler.pointerTracker touchesMoved:touches withEvent:event];
74
93
 
75
- CGPoint trans = [self translationInView];
76
- if ((_gestureHandler.shouldCancelWhenOutside && ![_gestureHandler containsPointInView]) ||
77
- (TEST_MAX_IF_NOT_NAN(
78
- fabs(trans.y * trans.y + trans.x * trans.x), self.allowableMovement * self.allowableMovement))) {
94
+ if ([self shouldCancelGesture]) {
95
+ self.state = UIGestureRecognizerStateFailed;
79
96
  self.enabled = NO;
80
97
  self.enabled = YES;
81
98
  }
@@ -94,6 +111,75 @@
94
111
  [self reset];
95
112
  }
96
113
 
114
+ #else
115
+ - (void)mouseDown:(NSEvent *)event
116
+ {
117
+ self.state = NSGestureRecognizerStateBegan;
118
+ startTime = CACurrentMediaTime();
119
+
120
+ [_gestureHandler.pointerTracker touchesBegan:[NSSet setWithObject:event] withEvent:event];
121
+
122
+ _initPosition = [self locationInView:self.view];
123
+
124
+ __weak typeof(self) weakSelf = self;
125
+
126
+ block = dispatch_block_create(0, ^{
127
+ __strong typeof(self) strongSelf = weakSelf;
128
+
129
+ if (strongSelf) {
130
+ strongSelf.state = NSGestureRecognizerStateChanged;
131
+ }
132
+ });
133
+
134
+ dispatch_after(
135
+ dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.minimumPressDuration * NSEC_PER_SEC)),
136
+ dispatch_get_main_queue(),
137
+ block);
138
+ }
139
+
140
+ - (void)mouseDragged:(NSEvent *)event
141
+ {
142
+ [_gestureHandler.pointerTracker touchesMoved:[NSSet setWithObject:event] withEvent:event];
143
+
144
+ if (block == nil) {
145
+ return;
146
+ }
147
+
148
+ if ([self shouldCancelGesture]) {
149
+ dispatch_block_cancel(block);
150
+ block = nil;
151
+
152
+ self.state = self.state == NSGestureRecognizerStateChanged ? NSGestureRecognizerStateCancelled
153
+ : NSGestureRecognizerStateFailed;
154
+ }
155
+ }
156
+
157
+ - (void)mouseUp:(NSEvent *)event
158
+ {
159
+ [_gestureHandler.pointerTracker touchesEnded:[NSSet setWithObject:event] withEvent:event];
160
+
161
+ if (block) {
162
+ dispatch_block_cancel(block);
163
+ block = nil;
164
+ }
165
+
166
+ self.state =
167
+ self.state == NSGestureRecognizerStateChanged ? NSGestureRecognizerStateEnded : NSGestureRecognizerStateFailed;
168
+ }
169
+
170
+ #endif
171
+
172
+ - (BOOL)shouldCancelGesture
173
+ {
174
+ CGPoint trans = [self translationInView];
175
+
176
+ BOOL shouldBeCancelledOutside = _gestureHandler.shouldCancelWhenOutside && ![_gestureHandler containsPointInView];
177
+ BOOL distanceExceeded =
178
+ TEST_MAX_IF_NOT_NAN(fabs(trans.y * trans.y + trans.x * trans.x), self.allowableMovement * self.allowableMovement);
179
+
180
+ return shouldBeCancelledOutside || distanceExceeded;
181
+ }
182
+
97
183
  - (void)reset
98
184
  {
99
185
  if (self.state == UIGestureRecognizerStateFailed) {
@@ -126,7 +212,7 @@
126
212
  - (void)resetConfig
127
213
  {
128
214
  [super resetConfig];
129
- UILongPressGestureRecognizer *recognizer = (UILongPressGestureRecognizer *)_recognizer;
215
+ RNBetterLongPressGestureRecognizer *recognizer = (RNBetterLongPressGestureRecognizer *)_recognizer;
130
216
 
131
217
  recognizer.minimumPressDuration = 0.5;
132
218
  recognizer.allowableMovement = 10;
@@ -135,7 +221,7 @@
135
221
  - (void)configure:(NSDictionary *)config
136
222
  {
137
223
  [super configure:config];
138
- UILongPressGestureRecognizer *recognizer = (UILongPressGestureRecognizer *)_recognizer;
224
+ RNBetterLongPressGestureRecognizer *recognizer = (RNBetterLongPressGestureRecognizer *)_recognizer;
139
225
 
140
226
  id prop = config[@"minDurationMs"];
141
227
  if (prop != nil) {
@@ -146,8 +232,15 @@
146
232
  if (prop != nil) {
147
233
  recognizer.allowableMovement = [RCTConvert CGFloat:prop];
148
234
  }
235
+
236
+ prop = config[@"numberOfPointers"];
237
+ if (prop != nil) {
238
+ recognizer.numberOfTouchesRequired = [RCTConvert CGFloat:prop];
239
+ }
149
240
  }
150
241
 
242
+ #if !TARGET_OS_OSX
243
+
151
244
  - (RNGestureHandlerState)state
152
245
  {
153
246
  // For long press recognizer we treat "Began" state as "active"
@@ -178,21 +271,17 @@
178
271
  withDuration:[(RNBetterLongPressGestureRecognizer *)recognizer getDuration]
179
272
  withPointerType:_pointerType];
180
273
  }
181
- @end
182
274
 
183
275
  #else
184
276
 
185
- @implementation RNLongPressGestureHandler
186
-
187
- - (instancetype)initWithTag:(NSNumber *)tag
277
+ - (RNGestureHandlerEventExtraData *)eventExtraData:(NSGestureRecognizer *)recognizer
188
278
  {
189
- RCTLogWarn(@"LongPressGestureHandler is not supported on macOS");
190
- if ((self = [super initWithTag:tag])) {
191
- _recognizer = [NSGestureRecognizer alloc];
192
- }
193
- return self;
279
+ return [RNGestureHandlerEventExtraData forPosition:[recognizer locationInView:recognizer.view]
280
+ withAbsolutePosition:[recognizer locationInView:recognizer.view.window.contentView]
281
+ withNumberOfTouches:1
282
+ withDuration:[(RNBetterLongPressGestureRecognizer *)recognizer getDuration]
283
+ withPointerType:RNGestureHandlerMouse];
194
284
  }
195
285
 
196
- @end
197
-
198
286
  #endif
287
+ @end
@@ -1,9 +1,10 @@
1
1
  #import "RNManualHandler.h"
2
2
 
3
3
  #if !TARGET_OS_OSX
4
-
5
4
  @interface RNManualRecognizer : UIGestureRecognizer
6
-
5
+ #else
6
+ @interface RNManualRecognizer : NSGestureRecognizer
7
+ #endif
7
8
  - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler;
8
9
 
9
10
  @end
@@ -19,25 +20,27 @@
19
20
  _gestureHandler = gestureHandler;
20
21
  _shouldSendBeginEvent = YES;
21
22
  }
23
+
22
24
  return self;
23
25
  }
24
26
 
25
- - (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
27
+ - (void)interactionsBegan:(NSSet *)touches withEvent:(UIEvent *)event
26
28
  {
27
- [_gestureHandler setCurrentPointerType:event];
28
- [super touchesBegan:touches withEvent:event];
29
29
  [_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
30
30
 
31
31
  if (_shouldSendBeginEvent) {
32
32
  [_gestureHandler handleGesture:self];
33
+ #if TARGET_OS_OSX
34
+ self.state = NSGestureRecognizerStateBegan;
35
+ #endif
33
36
  _shouldSendBeginEvent = NO;
34
37
  }
35
38
  }
36
39
 
37
- - (void)touchesMoved:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
40
+ - (void)interactionsMoved:(NSSet *)touches withEvent:(UIEvent *)event
38
41
  {
39
- [super touchesMoved:touches withEvent:event];
40
42
  [_gestureHandler.pointerTracker touchesMoved:touches withEvent:event];
43
+ [_gestureHandler handleGesture:self];
41
44
 
42
45
  if ([self shouldFail]) {
43
46
  self.state = (self.state == UIGestureRecognizerStatePossible) ? UIGestureRecognizerStateFailed
@@ -47,10 +50,31 @@
47
50
  }
48
51
  }
49
52
 
53
+ - (void)interactionsEnded:(NSSet *)touches withEvent:(UIEvent *)event
54
+ {
55
+ [_gestureHandler.pointerTracker touchesEnded:touches withEvent:event];
56
+ [_gestureHandler handleGesture:self];
57
+ }
58
+
59
+ #if !TARGET_OS_OSX
60
+ - (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
61
+ {
62
+ [_gestureHandler setCurrentPointerType:event];
63
+ [super touchesBegan:touches withEvent:event];
64
+
65
+ [self interactionsBegan:touches withEvent:event];
66
+ }
67
+
68
+ - (void)touchesMoved:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
69
+ {
70
+ [super touchesMoved:touches withEvent:event];
71
+ [self interactionsMoved:touches withEvent:event];
72
+ }
73
+
50
74
  - (void)touchesEnded:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
51
75
  {
52
76
  [super touchesEnded:touches withEvent:event];
53
- [_gestureHandler.pointerTracker touchesEnded:touches withEvent:event];
77
+ [self interactionsEnded:touches withEvent:event];
54
78
  }
55
79
 
56
80
  - (void)touchesCancelled:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
@@ -60,6 +84,26 @@
60
84
  [self reset];
61
85
  }
62
86
 
87
+ #else
88
+
89
+ - (void)mouseDown:(NSEvent *)event
90
+ {
91
+ [_gestureHandler setCurrentPointerTypeToMouse];
92
+ [self interactionsBegan:[NSSet setWithObject:event] withEvent:event];
93
+ }
94
+
95
+ - (void)mouseDragged:(NSEvent *)event
96
+ {
97
+ [self interactionsMoved:[NSSet setWithObject:event] withEvent:event];
98
+ }
99
+
100
+ - (void)mouseUp:(NSEvent *)event
101
+ {
102
+ [self interactionsEnded:[NSSet setWithObject:event] withEvent:event];
103
+ }
104
+
105
+ #endif
106
+
63
107
  - (void)reset
64
108
  {
65
109
  [_gestureHandler.pointerTracker reset];
@@ -71,11 +115,7 @@
71
115
 
72
116
  - (BOOL)shouldFail
73
117
  {
74
- if (_gestureHandler.shouldCancelWhenOutside && ![_gestureHandler containsPointInView]) {
75
- return YES;
76
- } else {
77
- return NO;
78
- }
118
+ return _gestureHandler.shouldCancelWhenOutside && ![_gestureHandler containsPointInView];
79
119
  }
80
120
 
81
121
  @end
@@ -87,24 +127,8 @@
87
127
  if ((self = [super initWithTag:tag])) {
88
128
  _recognizer = [[RNManualRecognizer alloc] initWithGestureHandler:self];
89
129
  }
90
- return self;
91
- }
92
-
93
- @end
94
-
95
- #else
96
-
97
- @implementation RNManualGestureHandler
98
130
 
99
- - (instancetype)initWithTag:(NSNumber *)tag
100
- {
101
- RCTLogWarn(@"ManualGestureHandler is not supported on macOS");
102
- if ((self = [super initWithTag:tag])) {
103
- _recognizer = [NSGestureRecognizer alloc];
104
- }
105
131
  return self;
106
132
  }
107
133
 
108
134
  @end
109
-
110
- #endif
@@ -44,6 +44,7 @@
44
44
 
45
45
  - (void)touchesMoved:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
46
46
  {
47
+ [self updateStateIfScrollView];
47
48
  [_gestureHandler.pointerTracker touchesMoved:touches withEvent:event];
48
49
  }
49
50
 
@@ -51,7 +52,12 @@
51
52
  {
52
53
  [_gestureHandler.pointerTracker touchesEnded:touches withEvent:event];
53
54
  self.state = UIGestureRecognizerStateFailed;
54
- [self reset];
55
+
56
+ // For now, we are handling only the scroll view case.
57
+ // If more views need special treatment, then we can switch to a delegate pattern
58
+ if ([_gestureHandler retrieveScrollView:self.view] == nil) {
59
+ [self reset];
60
+ }
55
61
  }
56
62
 
57
63
  - (void)touchesCancelled:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
@@ -92,6 +98,19 @@
92
98
  [_gestureHandler reset];
93
99
  }
94
100
 
101
+ - (void)updateStateIfScrollView
102
+ {
103
+ RNGHUIScrollView *scrollView = [_gestureHandler retrieveScrollView:self.view];
104
+ if (!scrollView) {
105
+ return;
106
+ }
107
+ for (UIGestureRecognizer *scrollViewGestureRecognizer in scrollView.gestureRecognizers) {
108
+ if ([_gestureHandler isUIScrollViewPanGestureRecognizer:scrollViewGestureRecognizer]) {
109
+ self.state = scrollViewGestureRecognizer.state;
110
+ }
111
+ }
112
+ }
113
+
95
114
  @end
96
115
 
97
116
  #pragma mark RNNativeViewGestureHandler
@@ -141,20 +160,8 @@
141
160
  // We can restore default scrollview behaviour to delay touches to scrollview's children
142
161
  // because gesture handler system can handle cancellation of scroll recognizer when JS responder
143
162
  // is set
144
- #ifdef RCT_NEW_ARCH_ENABLED
145
- if ([view isKindOfClass:[RCTScrollViewComponentView class]]) {
146
- UIScrollView *scrollView = ((RCTScrollViewComponentView *)view).scrollView;
147
- scrollView.delaysContentTouches = YES;
148
- }
149
- #else
150
- if ([view isKindOfClass:[RCTScrollView class]]) {
151
- // This part of the code is coupled with RN implementation of ScrollView native wrapper and
152
- // we expect for RCTScrollView component to contain a subclass of UIScrollview as the only
153
- // subview
154
- UIScrollView *scrollView = [view.subviews objectAtIndex:0];
155
- scrollView.delaysContentTouches = YES;
156
- }
157
- #endif // RCT_NEW_ARCH_ENABLED
163
+ UIScrollView *scrollView = [self retrieveScrollView:view];
164
+ scrollView.delaysContentTouches = YES;
158
165
  }
159
166
 
160
167
  - (void)handleTouchDown:(UIView *)sender forEvent:(UIEvent *)event
package/apple/RNGHUIKit.h CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  typedef UIView RNGHUIView;
6
6
  typedef UITouch RNGHUITouch;
7
+ typedef UIScrollView RNGHUIScrollView;
7
8
 
8
9
  #define RNGHGestureRecognizerStateFailed UIGestureRecognizerStateFailed;
9
10
  #define RNGHGestureRecognizerStatePossible UIGestureRecognizerStatePossible;
@@ -17,6 +18,7 @@ typedef UITouch RNGHUITouch;
17
18
 
18
19
  typedef RCTUIView RNGHUIView;
19
20
  typedef RCTUITouch RNGHUITouch;
21
+ typedef NSScrollView RNGHUIScrollView;
20
22
 
21
23
  #define RNGHGestureRecognizerStateFailed NSGestureRecognizerStateFailed;
22
24
  #define RNGHGestureRecognizerStatePossible NSGestureRecognizerStatePossible;
@@ -0,0 +1,31 @@
1
+ //
2
+ // RNGHVector.h
3
+ // Pods
4
+ //
5
+ // Created by Michał Bert on 05/08/2024.
6
+ //
7
+
8
+ #import "RNGestureHandlerDirection.h"
9
+
10
+ #ifndef RNGHVector_h
11
+ #define RNGHVector_h
12
+
13
+ @interface Vector : NSObject
14
+
15
+ @property (atomic, readonly, assign) double x;
16
+ @property (atomic, readonly, assign) double y;
17
+ @property (atomic, readonly, assign) double unitX;
18
+ @property (atomic, readonly, assign) double unitY;
19
+ @property (atomic, readonly, assign) double magnitude;
20
+
21
+ + (Vector *_Nonnull)fromDirection:(RNGestureHandlerDirection)direction;
22
+ + (Vector *_Nonnull)fromVelocityX:(double)vx withVelocityY:(double)vy;
23
+ - (nonnull instancetype)initWithX:(double)x withY:(double)y;
24
+ - (double)computeSimilarity:(Vector *_Nonnull)other;
25
+ - (BOOL)isSimilar:(Vector *_Nonnull)other withThreshold:(double)threshold;
26
+
27
+ @end
28
+
29
+ static double MINIMAL_RECOGNIZABLE_MAGNITUDE = 0.1;
30
+
31
+ #endif /* RNGHVector_h */
@@ -0,0 +1,67 @@
1
+ //
2
+ // RNGHVector.m
3
+ // DoubleConversion
4
+ //
5
+ // Created by Michał Bert on 05/08/2024.
6
+ //
7
+
8
+ #import "RNGHVector.h"
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @implementation Vector
12
+
13
+ - (id)initWithX:(double)x withY:(double)y
14
+ {
15
+ if (self = [super init]) {
16
+ _x = x;
17
+ _y = y;
18
+
19
+ _magnitude = hypot(x, y);
20
+
21
+ _unitX = self.magnitude > MINIMAL_RECOGNIZABLE_MAGNITUDE ? x / self.magnitude : 0;
22
+ _unitY = self.magnitude > MINIMAL_RECOGNIZABLE_MAGNITUDE ? y / self.magnitude : 0;
23
+ }
24
+
25
+ return self;
26
+ }
27
+
28
+ + (Vector *)fromDirection:(RNGestureHandlerDirection)direction
29
+ {
30
+ switch (direction) {
31
+ case RNGestureHandlerDirectionRight:
32
+ return [[Vector alloc] initWithX:1 withY:0];
33
+ case RNGestureHandlerDirectionLeft:
34
+ return [[Vector alloc] initWithX:-1 withY:0];
35
+ case RNGestureHandlerDirectionUp:
36
+ return [[Vector alloc] initWithX:0 withY:1];
37
+ case RNGestureHandlerDirectionDown:
38
+ return [[Vector alloc] initWithX:0 withY:-1];
39
+ case RNGestureHandlerDirectionUpLeft:
40
+ return [[Vector alloc] initWithX:-1 withY:1];
41
+ case RNGestureHandlerDirectionUpRight:
42
+ return [[Vector alloc] initWithX:1 withY:1];
43
+ case RNGestureHandlerDirectionDownLeft:
44
+ return [[Vector alloc] initWithX:-1 withY:-1];
45
+ case RNGestureHandlerDirectionDownRight:
46
+ return [[Vector alloc] initWithX:1 withY:-1];
47
+ default:
48
+ return [[Vector alloc] initWithX:0 withY:0];
49
+ }
50
+ }
51
+
52
+ + (Vector *)fromVelocityX:(double)vx withVelocityY:(double)vy;
53
+ {
54
+ return [[Vector alloc] initWithX:vx withY:vy];
55
+ }
56
+
57
+ - (double)computeSimilarity:(Vector *)other
58
+ {
59
+ return self.unitX * other.unitX + self.unitY * other.unitY;
60
+ }
61
+
62
+ - (BOOL)isSimilar:(Vector *)other withThreshold:(double)threshold
63
+ {
64
+ return [self computeSimilarity:other] > threshold;
65
+ }
66
+
67
+ @end
@@ -89,6 +89,13 @@
89
89
  withExtraData:(nonnull RNGestureHandlerEventExtraData *)extraData;
90
90
  - (void)sendEvent:(nonnull RNGestureHandlerStateChange *)event;
91
91
  - (void)sendTouchEventInState:(RNGestureHandlerState)state forViewWithTag:(nonnull NSNumber *)reactTag;
92
+ - (nullable RNGHUIScrollView *)retrieveScrollView:(nonnull RNGHUIView *)view;
93
+
94
+ #if !TARGET_OS_OSX
95
+ - (BOOL)isUIScrollViewPanGestureRecognizer:(nonnull UIGestureRecognizer *)gestureRecognizer;
96
+ #else
97
+ - (BOOL)isUIScrollViewPanGestureRecognizer:(nonnull NSGestureRecognizer *)gestureRecognizer;
98
+ #endif
92
99
 
93
100
  #if !TARGET_OS_OSX
94
101
  - (void)setCurrentPointerType:(nonnull UIEvent *)event;
@@ -5,10 +5,17 @@
5
5
 
6
6
  #if !TARGET_OS_OSX
7
7
  #import <UIKit/UIGestureRecognizerSubclass.h>
8
+ #import <UIKit/UIPanGestureRecognizer.h>
8
9
  #endif
9
10
 
10
11
  #import <React/UIView+React.h>
11
12
 
13
+ #ifdef RCT_NEW_ARCH_ENABLED
14
+ #import <React/RCTScrollViewComponentView.h>
15
+ #else
16
+ #import <React/RCTScrollView.h>
17
+ #endif
18
+
12
19
  @interface UIGestureRecognizer (GestureHandler)
13
20
  @property (nonatomic, readonly) RNGestureHandler *gestureHandler;
14
21
  @end
@@ -205,7 +212,7 @@ static NSHashTable<RNGestureHandler *> *allGestureHandlers;
205
212
 
206
213
  - (UITouchType)getPointerType
207
214
  {
208
- return _pointerType;
215
+ return (UITouchType)_pointerType;
209
216
  }
210
217
 
211
218
  - (void)bindToView:(RNGHUIView *)view
@@ -474,6 +481,10 @@ static NSHashTable<RNGestureHandler *> *allGestureHandlers;
474
481
  return YES;
475
482
  }
476
483
 
484
+ if ([self areScrollViewRecognizersCompatible:gestureRecognizer otherRecognizer:otherGestureRecognizer]) {
485
+ return YES;
486
+ }
487
+
477
488
  RNGestureHandler *handler = [RNGestureHandler findGestureHandlerByRecognizer:otherGestureRecognizer];
478
489
  if (handler != nil) {
479
490
  if ([_simultaneousHandlers count]) {
@@ -495,6 +506,57 @@ static NSHashTable<RNGestureHandler *> *allGestureHandlers;
495
506
  return NO;
496
507
  }
497
508
 
509
+ - (BOOL)areScrollViewRecognizersCompatible:(UIGestureRecognizer *)gestureRecognizer
510
+ otherRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
511
+ {
512
+ if ([self isUIScrollViewPanGestureRecognizer:otherGestureRecognizer] &&
513
+ [gestureRecognizer isKindOfClass:[RNDummyGestureRecognizer class]]) {
514
+ RNGHUIScrollView *scrollView = [self retrieveScrollView:gestureRecognizer.view];
515
+ if (scrollView && scrollView == otherGestureRecognizer.view) {
516
+ return YES;
517
+ }
518
+ }
519
+
520
+ return NO;
521
+ }
522
+
523
+ #if !TARGET_OS_OSX
524
+ // is UIPanGestureRecognizer and has scrollView property
525
+ - (BOOL)isUIScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
526
+ {
527
+ return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] &&
528
+ [gestureRecognizer respondsToSelector:@selector(scrollView)];
529
+ }
530
+
531
+ #else
532
+
533
+ - (BOOL)isUIScrollViewPanGestureRecognizer:(NSGestureRecognizer *)gestureRecognizer
534
+ {
535
+ return NO;
536
+ }
537
+
538
+ #endif
539
+
540
+ - (RNGHUIScrollView *)retrieveScrollView:(RNGHUIView *)view
541
+ {
542
+ #ifdef RCT_NEW_ARCH_ENABLED
543
+ if ([view isKindOfClass:[RCTScrollViewComponentView class]]) {
544
+ RNGHUIScrollView *scrollView = ((RCTScrollViewComponentView *)view).scrollView;
545
+ return scrollView;
546
+ }
547
+ #else
548
+ if ([view isKindOfClass:[RCTScrollView class]]) {
549
+ // This part of the code is coupled with RN implementation of ScrollView native wrapper and
550
+ // we expect for RCTScrollView component to contain a subclass of UIScrollview as the only
551
+ // subview
552
+ RNGHUIScrollView *scrollView = [view.subviews objectAtIndex:0];
553
+ return scrollView;
554
+ }
555
+ #endif
556
+
557
+ return nil;
558
+ }
559
+
498
560
  - (void)reset
499
561
  {
500
562
  // do not reset states while gesture is tracking pointers, as gestureRecognizerShouldBegin
@@ -21,6 +21,12 @@ using namespace facebook::react;
21
21
  RNGestureHandlerButton *_buttonView;
22
22
  }
23
23
 
24
+ // Needed because of this: https://github.com/facebook/react-native/pull/37274
25
+ + (void)load
26
+ {
27
+ [super load];
28
+ }
29
+
24
30
  - (instancetype)initWithFrame:(CGRect)frame
25
31
  {
26
32
  if (self = [super initWithFrame:frame]) {
@@ -1,8 +1,33 @@
1
1
  #import <Foundation/Foundation.h>
2
2
 
3
+ #ifndef RNGestureHandlerDirection_h
4
+ #define RNGestureHandlerDirection_h
5
+
3
6
  typedef NS_ENUM(NSInteger, RNGestureHandlerDirection) {
4
7
  RNGestureHandlerDirectionRight = 1,
5
8
  RNGestureHandlerDirectionLeft = 2,
6
9
  RNGestureHandlerDirectionUp = 4,
7
10
  RNGestureHandlerDirectionDown = 8,
11
+ RNGestureHandlerDirectionUpLeft = RNGestureHandlerDirectionUp | RNGestureHandlerDirectionLeft,
12
+ RNGestureHandlerDirectionUpRight = RNGestureHandlerDirectionUp | RNGestureHandlerDirectionRight,
13
+ RNGestureHandlerDirectionDownLeft = RNGestureHandlerDirectionDown | RNGestureHandlerDirectionLeft,
14
+ RNGestureHandlerDirectionDownRight = RNGestureHandlerDirectionDown | RNGestureHandlerDirectionRight,
15
+ };
16
+
17
+ static NSInteger axialDirections[] = {
18
+ RNGestureHandlerDirectionRight,
19
+ RNGestureHandlerDirectionLeft,
20
+ RNGestureHandlerDirectionUp,
21
+ RNGestureHandlerDirectionDown,
8
22
  };
23
+
24
+ static NSInteger diagonalDirections[] = {
25
+ RNGestureHandlerDirectionUpLeft,
26
+ RNGestureHandlerDirectionUpRight,
27
+ RNGestureHandlerDirectionDownLeft,
28
+ RNGestureHandlerDirectionDownRight,
29
+ };
30
+
31
+ static NSInteger directionsSize = 4;
32
+
33
+ #endif
@@ -99,10 +99,8 @@ void decorateRuntime(jsi::Runtime &runtime)
99
99
  if (!arguments[0].isObject()) {
100
100
  return jsi::Value::null();
101
101
  }
102
-
103
- auto shadowNodeWrapper = arguments[0].asObject(runtime).getNativeState<ShadowNodeWrapper>(runtime);
104
- bool isFormsStackingContext =
105
- shadowNodeWrapper->shadowNode->getTraits().check(ShadowNodeTraits::FormsStackingContext);
102
+ auto shadowNode = shadowNodeFromValue(runtime, arguments[0]);
103
+ bool isFormsStackingContext = shadowNode->getTraits().check(ShadowNodeTraits::FormsStackingContext);
106
104
  return jsi::Value(isFormsStackingContext);
107
105
  });
108
106
  runtime.global().setProperty(runtime, "isFormsStackingContext", std::move(isFormsStackingContext));