Skip to content

Commit d95aa05

Browse files
authored
Fix reattaching (#3960)
## Description On both iOS and Android gesture reattaching did not work. The registry did not check which detector was the gesture attached to before detaching. As a result, when detaching from old detector it accidentally detached the gesture from the new one. ## Test plan Tested on the following example <details> ```tsx import { commonStyles } from '../common-app/src/common'; import React, { useState } from 'react'; import { View } from 'react-native'; import { GestureDetector, GestureHandlerRootView, useTapGesture } from 'react-native-gesture-handler'; export default function TapExample() { const [isTopActive, setIsTopActive] = useState(false); const tap = useTapGesture({ onActivate: () => { console.log((isTopActive ? "top" : "bottom"), " clicked"); setIsTopActive(prev => !prev); }, disableReanimated: true }) const noopGesture = useTapGesture({}); return ( <GestureHandlerRootView> <View style={commonStyles.centerView}> <GestureDetector gesture={isTopActive ? tap : noopGesture}> <View style={[commonStyles.box, { backgroundColor: isTopActive ? "red" : "blue" }]} /> </GestureDetector> <GestureDetector gesture={isTopActive ? noopGesture : tap}> <View style={[commonStyles.box, { backgroundColor: isTopActive ? "blue" : "red" }]} /> </GestureDetector> </View> </GestureHandlerRootView> ); } ``` </details>
1 parent 6edaba5 commit d95aa05

5 files changed

Lines changed: 16 additions & 12 deletions

File tree

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
109109
}
110110

111111
for (tag in handlersToDetach) {
112-
registry.detachHandler(tag)
112+
registry.detachHandlerFromHostDetector(tag, this)
113113
nativeHandlers.remove(tag)
114114
attachedHandlers.remove(tag)
115115
}
@@ -134,7 +134,7 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
134134

135135
for (child in virtualChildrenToDetach) {
136136
for (tag in attachedVirtualHandlers[child]!!) {
137-
registry.detachHandler(tag)
137+
registry.detachHandlerFromHostDetector(tag, this)
138138
}
139139
attachedVirtualHandlers.remove(tag)
140140
}
@@ -182,7 +182,7 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
182182
?: throw Exception("Tried to access a non-existent registry")
183183

184184
for (tag in nativeHandlers) {
185-
registry.detachHandler(tag)
185+
registry.detachHandlerFromHostDetector(tag, this)
186186
attachedHandlers.remove(tag)
187187
}
188188
}
@@ -197,13 +197,13 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
197197
?: throw Exception("Tried to access a non-existent registry")
198198

199199
for (tag in attachedHandlers.toMutableSet()) {
200-
registry.detachHandler(tag)
200+
registry.detachHandlerFromHostDetector(tag, this)
201201
attachedHandlers.remove(tag)
202202
}
203203

204204
for (child in attachedVirtualHandlers) {
205205
for (tag in child.value) {
206-
registry.detachHandler(tag)
206+
registry.detachHandlerFromHostDetector(tag, this)
207207
}
208208
child.value.clear()
209209
}

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRegistry.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ class RNGestureHandlerRegistry : GestureHandlerRegistry {
7878
}
7979

8080
@Synchronized
81-
fun detachHandler(handlerTag: Int) {
81+
fun detachHandlerFromHostDetector(handlerTag: Int, hostDetectorView: RNGestureHandlerDetectorView?) {
8282
handlers[handlerTag]?.let {
83+
if (it.hostDetectorView != hostDetectorView) return
8384
detachHandlerInternal(it)
8485
}
8586
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ - (void)willMoveToWindow:(RNGHWindow *)newWindow
5353

5454
for (const auto handler : props.handlerTags) {
5555
NSNumber *handlerTag = [NSNumber numberWithInt:handler];
56-
[handlerManager.registry detachHandlerWithTag:handlerTag];
56+
[handlerManager.registry detachHandlerWithTag:handlerTag fromHostDetector:self];
5757
}
5858
for (const auto &child : _attachedVirtualHandlers) {
5959
for (id handlerTag : child.second) {
60-
[handlerManager.registry detachHandlerWithTag:handlerTag];
60+
[handlerManager.registry detachHandlerWithTag:handlerTag fromHostDetector:self];
6161
}
6262
}
6363
_attachedVirtualHandlers.clear();
@@ -232,7 +232,7 @@ - (void)attachHandlers:(const std::vector<int> &)handlerTags
232232
}
233233

234234
for (const id tag : handlersToDetach) {
235-
[handlerManager.registry detachHandlerWithTag:tag];
235+
[handlerManager.registry detachHandlerWithTag:tag fromHostDetector:self];
236236
[attachedHandlers removeObject:tag];
237237
[_nativeHandlers removeObject:tag];
238238
}
@@ -276,7 +276,7 @@ - (void)updateVirtualChildren:(const std::vector<RNGestureHandlerDetectorVirtual
276276

277277
for (const NSNumber *tag : virtualChildrenToDetach) {
278278
for (id handlerTag : _attachedVirtualHandlers[tag.intValue]) {
279-
[handlerManager.registry detachHandlerWithTag:handlerTag];
279+
[handlerManager.registry detachHandlerWithTag:handlerTag fromHostDetector:self];
280280
}
281281
_attachedVirtualHandlers.erase(tag.intValue);
282282
}
@@ -326,7 +326,7 @@ - (void)detachNativeGestureHandlers
326326
RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId:_moduleId];
327327

328328
for (NSNumber *handlerTag in _nativeHandlers) {
329-
[[handlerManager registry] detachHandlerWithTag:handlerTag];
329+
[[handlerManager registry] detachHandlerWithTag:handlerTag fromHostDetector:self];
330330
[_attachedHandlers removeObject:handlerTag];
331331
}
332332
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
withActionType:(RNGestureHandlerActionType)actionType
1818
withHostDetector:(nullable RNGHUIView *)hostDetector;
1919
- (void)detachHandlerWithTag:(nonnull NSNumber *)handlerTag;
20+
- (void)detachHandlerWithTag:(nonnull NSNumber *)handlerTag fromHostDetector:(nonnull RNGHUIView *)hostDetectorView;
2021
- (void)dropHandlerWithTag:(nonnull NSNumber *)handlerTag;
2122
- (void)dropAllHandlers;
2223

packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ - (void)attachHandlerWithTag:(NSNumber *)handlerTag
4848
}
4949
}
5050

51-
- (void)detachHandlerWithTag:(NSNumber *)handlerTag
51+
- (void)detachHandlerWithTag:(NSNumber *)handlerTag fromHostDetector:(RNGHUIView *)hostDetectorView
5252
{
5353
RNGestureHandler *handler = _handlers[handlerTag];
54+
if (handler.hostDetectorView != hostDetectorView)
55+
return;
5456
[handler unbindFromView];
5557
}
5658

0 commit comments

Comments
 (0)