Skip to content

Commit 52e082f

Browse files
fix: remove UIPointerInteraction from the view when unbinding the hover handler (#4291)
## Description Fixes #4290. `RNHoverGestureHandler` adds a `UIPointerInteraction` to the view in `bindToView:`, but never actually removes it. In `unbindFromView`, `[super unbindFromView]` runs first and detaches the gesture recognizer, which sets `self.recognizer.view` to nil. The following `removeInteraction:` call is then a message to nil and does nothing, so the interaction stays on the `UIView` for the rest of its life. With Fabric view recycling, that leaked interaction later belongs to an unrelated component. Its delegate (the recognizer) is gone by then, and a `UIPointerInteraction` without a delegate applies the system default pointer effect over the whole view. The visible result is native hover effects (very prominent with the Liquid Glass style on iPadOS 26) appearing on random elements that never had a hover gesture, accumulating as hover handlers unmount and remount. This PR captures the view reference before calling `[super unbindFromView]` and removes the interaction from the captured reference. ## Test plan Tested in an app that uses `Gesture.Hover()` on most of its toolbar and menu items, on a real iPad (iPadOS 26) with Apple Pencil hover and a trackpad: - Before the change: after a few mount/unmount cycles of hover-enabled views, hovering over unrelated elements shows the native hover effect on random views. - With the change (applied to the app as a package patch): the stray hover effects no longer appear, and hover gestures keep working as before. - The `RNGestureHandler` pod compiles cleanly with the change.
1 parent a373442 commit 52e082f

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ - (void)unbindFromView
122122
{
123123
#if CHECK_TARGET(13_4)
124124
if (@available(iOS 13.4, *)) {
125-
[super unbindFromView];
125+
// Remove the interaction before [super unbindFromView] detaches the recognizer and nils recognizer.view.
126126
[self.recognizer.view removeInteraction:_pointerInteraction];
127+
[super unbindFromView];
127128
}
128129
#endif
129130
}

0 commit comments

Comments
 (0)