Skip to content

Commit af8b121

Browse files
akwasniewskiCopilotCopilotm-bert
authored
[ios] not calling activation callback on inactive gestures (#3986)
## Description Gestures always call activation callback upon finalizing, regardless of the previous state. This is intended for normal gestures, however for manually handled gestures we don't want to call it. This PR unifies the behaviour across platforms, GestureManager.finalize() won't call activation callback. ## Test plan Tested on the state manager example --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: m-bert <[email protected]>
1 parent f46080a commit af8b121

File tree

10 files changed

+71
-23
lines changed

10 files changed

+71
-23
lines changed

packages/react-native-gesture-handler/apple/Handlers/RNFlingHandler.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ - (void)touchesCancelled:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)ev
7070

7171
- (void)triggerAction
7272
{
73-
[_gestureHandler handleGesture:self fromReset:NO];
73+
[_gestureHandler handleGesture:self fromReset:NO fromManualStateChange:NO];
7474
}
7575

7676
- (void)triggerActionFromReset
7777
{
78-
[_gestureHandler handleGesture:self fromReset:YES];
78+
[_gestureHandler handleGesture:self fromReset:YES fromManualStateChange:NO];
7979
}
8080

8181
- (void)reset

packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ - (void)handleGesture:(UIHoverGestureRecognizer *)recognizer
5858

5959
- (void)triggerAction
6060
{
61-
[_gestureHandler handleGesture:self fromReset:NO];
61+
[_gestureHandler handleGesture:self fromReset:NO fromManualStateChange:NO];
6262
}
6363

6464
- (void)cancel

packages/react-native-gesture-handler/apple/Handlers/RNLongPressHandler.m

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ - (NSUInteger)getDuration;
3434

3535
#if !TARGET_OS_OSX
3636
- (void)handleGesture:(UIGestureRecognizer *)recognizer;
37-
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset;
37+
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange;
3838
#else
3939
- (void)handleGesture:(NSGestureRecognizer *)recognizer;
40-
- (void)handleGesture:(NSGestureRecognizer *)recognizer fromReset:(BOOL)fromReset;
40+
- (void)handleGesture:(NSGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange;
4141
#endif
4242

4343
@end
@@ -57,24 +57,23 @@ - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
5757

5858
- (void)handleGesture:(UIGestureRecognizer *)recognizer
5959
{
60-
previousTime = CACurrentMediaTime();
61-
[_gestureHandler handleGesture:recognizer fromReset:NO];
60+
[self handleGesture:recognizer fromReset:NO fromManualStateChange:NO];
6261
}
6362

64-
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset
63+
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange
6564
{
6665
previousTime = CACurrentMediaTime();
67-
[_gestureHandler handleGesture:recognizer fromReset:fromReset];
66+
[_gestureHandler handleGesture:recognizer fromReset:fromReset fromManualStateChange:fromManualStateChange];
6867
}
6968

7069
- (void)triggerAction
7170
{
72-
[self handleGesture:self fromReset:NO];
71+
[self handleGesture:self fromReset:NO fromManualStateChange:NO];
7372
}
7473

7574
- (void)triggerActionFromReset
7675
{
77-
[self handleGesture:self fromReset:YES];
76+
[self handleGesture:self fromReset:YES fromManualStateChange:NO];
7877
}
7978

8079
- (CGPoint)translationInView

packages/react-native-gesture-handler/apple/Handlers/RNPanHandler.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
7575

7676
- (void)triggerAction
7777
{
78-
[_gestureHandler handleGesture:self fromReset:NO];
78+
[_gestureHandler handleGesture:self fromReset:NO fromManualStateChange:NO];
7979
}
8080

8181
- (void)triggerActionFromReset
8282
{
83-
[_gestureHandler handleGesture:self fromReset:YES];
83+
[_gestureHandler handleGesture:self fromReset:YES fromManualStateChange:NO];
8484
}
8585

8686
#if !TARGET_OS_OSX

packages/react-native-gesture-handler/apple/Handlers/RNPinchHandler.m

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
4444
}
4545

4646
- (void)handleGesture:(UIGestureRecognizer *)recognizer
47+
{
48+
[self handleGesture:recognizer fromReset:NO fromManualStateChange:NO];
49+
}
50+
51+
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange
4752
{
4853
if (self.state == UIGestureRecognizerStateBegan) {
4954
#if TARGET_OS_OSX
@@ -52,8 +57,7 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer
5257
self.scale = 1;
5358
#endif
5459
}
55-
56-
[_gestureHandler handleGesture:recognizer fromReset:NO];
60+
[_gestureHandler handleGesture:recognizer fromReset:fromReset fromManualStateChange:fromManualStateChange];
5761
}
5862

5963
- (void)interactionsBegan:(NSSet *)touches withEvent:(UIEvent *)event

packages/react-native-gesture-handler/apple/Handlers/RNRotationHandler.m

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,16 @@ - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
4242
}
4343

4444
- (void)handleGesture:(UIGestureRecognizer *)recognizer
45+
{
46+
[self handleGesture:recognizer fromReset:NO fromManualStateChange:NO];
47+
}
48+
49+
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange
4550
{
4651
if (self.state == UIGestureRecognizerStateBegan) {
4752
self.rotation = 0;
4853
}
49-
[_gestureHandler handleGesture:recognizer fromReset:NO];
54+
[_gestureHandler handleGesture:recognizer fromReset:fromReset fromManualStateChange:fromManualStateChange];
5055
}
5156

5257
- (void)interactionsBegan:(NSSet *)touches withEvent:(UIEvent *)event

packages/react-native-gesture-handler/apple/Handlers/RNTapHandler.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
6363

6464
- (void)triggerAction
6565
{
66-
[_gestureHandler handleGesture:self fromReset:NO];
66+
[_gestureHandler handleGesture:self fromReset:NO fromManualStateChange:NO];
6767
}
6868

6969
- (void)triggerActionFromReset
7070
{
71-
[_gestureHandler handleGesture:self fromReset:YES];
71+
[_gestureHandler handleGesture:self fromReset:YES fromManualStateChange:NO];
7272
}
7373

7474
- (void)cancel

packages/react-native-gesture-handler/apple/RNGestureHandler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
- (void)updateRelations:(nonnull NSDictionary *)relations;
9898
- (void)handleGesture:(nonnull id)recognizer;
9999
- (void)handleGesture:(nonnull id)recognizer fromReset:(BOOL)fromReset;
100+
- (void)handleGesture:(nonnull id)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange;
100101
- (void)handleGesture:(nonnull id)recognizer inState:(RNGestureHandlerState)state;
102+
- (void)handleGesture:(nonnull id)recognizer inState:(RNGestureHandlerState)state fromManualStateChange:(BOOL)fromManualStateChange;
101103
- (BOOL)containsPointInView;
102104
- (RNGestureHandlerState)state;
103105
- (nullable RNGestureHandlerEventExtraData *)eventExtraData:(nonnull id)recognizer;
@@ -107,6 +109,10 @@
107109
- (void)sendEventsInState:(RNGestureHandlerState)state
108110
forViewWithTag:(nonnull NSNumber *)reactTag
109111
withExtraData:(nonnull RNGestureHandlerEventExtraData *)extraData;
112+
- (void)sendEventsInState:(RNGestureHandlerState)state
113+
forViewWithTag:(nonnull NSNumber *)reactTag
114+
withExtraData:(nonnull RNGestureHandlerEventExtraData *)extraData
115+
fromManualStateChange:(BOOL)fromManualStateChange;
110116
- (void)sendEvent:(nonnull RNGestureHandlerStateChange *)event;
111117
- (void)sendTouchEventInState:(RNGestureHandlerState)state forViewWithTag:(nonnull NSNumber *)reactTag;
112118
- (nullable RNGHUIScrollView *)retrieveScrollView:(nonnull RNGHUIView *)view;

packages/react-native-gesture-handler/apple/RNGestureHandler.mm

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,13 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer
313313
}
314314

315315
- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset
316+
{
317+
[self handleGesture:recognizer fromReset:fromReset fromManualStateChange:NO];
318+
}
319+
320+
- (void)handleGesture:(UIGestureRecognizer *)recognizer
321+
fromReset:(BOOL)fromReset
322+
fromManualStateChange:(BOOL)fromManualStateChange
316323
{
317324
// Don't dispatch state changes from undetermined when resetting handler. There will be no follow-up
318325
// since the handler is being reset, so these events are wrong.
@@ -345,10 +352,17 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromRese
345352
_state = RNGestureHandlerStateFailed;
346353
}
347354

348-
[self handleGesture:recognizer inState:_state];
355+
[self handleGesture:recognizer inState:_state fromManualStateChange:fromManualStateChange];
349356
}
350357

351358
- (void)handleGesture:(UIGestureRecognizer *)recognizer inState:(RNGestureHandlerState)state
359+
{
360+
[self handleGesture:recognizer inState:state fromManualStateChange:NO];
361+
}
362+
363+
- (void)handleGesture:(UIGestureRecognizer *)recognizer
364+
inState:(RNGestureHandlerState)state
365+
fromManualStateChange:(BOOL)fromManualStateChange
352366
{
353367
_state = state;
354368

@@ -366,7 +380,10 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer inState:(RNGestureHandle
366380

367381
react_native_assert(tag != nil && "Tag should be defined when dispatching an event");
368382

369-
[self sendEventsInState:self.state forViewWithTag:tag withExtraData:eventData];
383+
[self sendEventsInState:self.state
384+
forViewWithTag:tag
385+
withExtraData:eventData
386+
fromManualStateChange:fromManualStateChange];
370387
}
371388

372389
- (RNGestureHandlerEventHandlerType)eventHandlerType
@@ -379,6 +396,14 @@ - (RNGestureHandlerEventHandlerType)eventHandlerType
379396
- (void)sendEventsInState:(RNGestureHandlerState)state
380397
forViewWithTag:(nonnull NSNumber *)reactTag
381398
withExtraData:(RNGestureHandlerEventExtraData *)extraData
399+
{
400+
[self sendEventsInState:state forViewWithTag:reactTag withExtraData:extraData fromManualStateChange:NO];
401+
}
402+
403+
- (void)sendEventsInState:(RNGestureHandlerState)state
404+
forViewWithTag:(nonnull NSNumber *)reactTag
405+
withExtraData:(RNGestureHandlerEventExtraData *)extraData
406+
fromManualStateChange:(BOOL)fromManualStateChange
382407
{
383408
if (state != _lastState) {
384409
// don't send change events from END to FAILED or CANCELLED, this may happen when gesture is ended in `onTouchesUp`
@@ -397,14 +422,23 @@ - (void)sendEventsInState:(RNGestureHandlerState)state
397422
return;
398423
}
399424

425+
if (state == RNGestureHandlerStateEnd && _lastState == RNGestureHandlerStateUndetermined &&
426+
(fromManualStateChange || _manualActivation)) {
427+
_lastState = state;
428+
return;
429+
}
430+
400431
if (state == RNGestureHandlerStateActive) {
401432
// Generate a unique coalescing-key each time the gesture-handler becomes active. All events will have
402433
// the same coalescing-key allowing RCTEventDispatcher to coalesce RNGestureHandlerEvents when events are
403434
// generated faster than they can be treated by JS thread
404435
static uint16_t nextEventCoalescingKey = 0;
405436
self->_eventCoalescingKey = nextEventCoalescingKey++;
406437

407-
} else if (state == RNGestureHandlerStateEnd && _lastState != RNGestureHandlerStateActive && !_manualActivation) {
438+
} else if (
439+
state == RNGestureHandlerStateEnd && _lastState != RNGestureHandlerStateActive && !fromManualStateChange &&
440+
!_manualActivation) {
441+
// Otherwise send activate state change event to preserve correct gesture flow
408442
id event = [[RNGestureHandlerStateChange alloc] initWithReactTag:reactTag
409443
handlerTag:_tag
410444
state:RNGestureHandlerStateActive

packages/react-native-gesture-handler/apple/RNGestureHandlerModule.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ - (void)setGestureStateSync:(int)state forHandler:(int)handlerTag
227227
} else if (state == 4) { // ACTIVE
228228
if (handler.recognizer.state == UIGestureRecognizerStatePossible) {
229229
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve the correct state transition flow.
230-
[handler handleGesture:handler.recognizer fromReset:NO];
230+
[handler handleGesture:handler.recognizer fromReset:NO fromManualStateChange:YES];
231231
}
232232
[handler stopActivationBlocker];
233233
handler.recognizer.state = RNGHGestureRecognizerStateBegan;
@@ -244,7 +244,7 @@ - (void)setGestureStateSync:(int)state forHandler:(int)handlerTag
244244
// do not send state change event when activating because it bypasses
245245
// shouldRequireFailureOfGestureRecognizer
246246
if (state != 4) {
247-
[handler handleGesture:handler.recognizer fromReset:NO];
247+
[handler handleGesture:handler.recognizer fromReset:NO fromManualStateChange:YES];
248248
}
249249
}
250250

0 commit comments

Comments
 (0)