fix: remove UIPointerInteraction from the view when unbinding the hover handler#4291
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes an iOS hover interaction leak in RNHoverGestureHandler by ensuring the UIPointerInteraction added in bindToView: is reliably removed during unbindFromView, preventing stray system hover effects on Fabric-recycled views.
Changes:
- Capture the bound
UIViewreference before calling[super unbindFromView](which clearsrecognizer.view). - Remove
_pointerInteractionfrom the captured view instead of fromself.recognizer.viewafter it becomesnil.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ed75cd7 to
5ec9f49
Compare
|
Standalone repro, with results detailed in #4290: https://github.com/petterikorpimaa/rngh-hover-leak-repro Verified this fix against it on a real iPad (iPadOS 26, RN 0.86.0, RNGH 2.32.0). Without the fix: a deterministic three-tap repro shows the leaked native hover effect on a still-mounted view, recycled views spread it to unrelated components, and unmounting a poisoned view after hovering it aborts the app in a Fabric assertion ( |
Description
Fixes #4290.
RNHoverGestureHandleradds aUIPointerInteractionto the view inbindToView:, but never actually removes it. InunbindFromView,[super unbindFromView]runs first and detaches the gesture recognizer, which setsself.recognizer.viewto nil. The followingremoveInteraction:call is then a message to nil and does nothing, so the interaction stays on theUIViewfor 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
UIPointerInteractionwithout 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:RNGestureHandlerpod compiles cleanly with the change.