Skip to content

fix(ios): prevent menu-dismissal taps from triggering underlying views - #177

Open
arobdog wants to merge 1 commit into
mpiannucci:mainfrom
arobdog:fix/menu-dismiss-tap-passthrough
Open

fix(ios): prevent menu-dismissal taps from triggering underlying views#177
arobdog wants to merge 1 commit into
mpiannucci:mainfrom
arobdog:fix/menu-dismiss-tap-passthrough

Conversation

@arobdog

@arobdog arobdog commented Jul 28, 2026

Copy link
Copy Markdown

Problem

On iOS, the tap that dismisses an open context menu is also delivered to the app window, so React Native pressables underneath it fire. Dismissing a menu by tapping elsewhere can press a button, select a row, or navigate - reported in #120, and reproducible in both dropdownMenuMode and the long-press flow.

Fix

While a menu is displayed, cover the window with a transparent UIView that consumes every touch, and remove it when the menu ends. The menu itself is unaffected (it lives in its own system window above the app's). This is the approach posted in #120's thread (credit to that diff), with two changes found necessary in production use:

  • Removal is keyed to the configuration that actually displayed. The view attaches two menu interactions sharing one delegate (the dropdown tap path and the long-press path), and the interaction that never displayed also reaches willEndForConfiguration — on the long-press path this happens at finger release, while the menu is still open. Unguarded, that removes the scrim early (reintroducing the bug for long-press-opened menus) and fires a spurious onCancel. The same guard therefore also fixes onCancel firing while the menu is still visible.
  • The scrim attaches to the window rather than the view controller's view, so content outside the hosting controller (e.g. a native tab bar) is covered too, and it's cleaned up in didMoveToWindow if the view unmounts while a menu is open.

Android needs no equivalent: its native menu consumes the outside-dismiss touch (verified on device).

Testing

Verified in a production React Native app (new architecture, RN 0.7x) on iOS simulator and devices: menus opened by tap and by long-press; dismissal taps on rows/buttons/tab bar only dismiss; menu item selection, onPress, and onCancel all behave as before; no scrim leak after unmount-while-open.

Closes #120

The tap that dismisses an open context menu is also delivered to the app
window, so React Native pressables underneath fire — dismissing a menu
could press a button or navigate. While a menu is displayed, cover the
window with a transparent view that consumes touches, removed when the
menu ends.

Removal (and onCancel) is keyed to the configuration that actually
displayed: the view attaches two menu interactions sharing one delegate,
and the one that never displayed also reaches willEndForConfiguration —
on the long-press path at finger release, while the menu is still open —
which would otherwise remove the scrim early and fire a spurious
onCancel.

Closes mpiannucci#120
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prevent action on react native buttons while context menu is presented and support adding a title to Android context menu

1 participant