react-native-gesture-handler 2.18.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
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));