react / react/react-native

iOS: selectable Text edit menu flickers on long-press release (handleLongPress ignores gesture.state)

Open Beginner friendly
#58,079 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs: Author Feedback Needs: Repro Stale
Dominant language
C++
Stars
127k
Forks
25.3k
Avg merge
1d 23h
Merged PRs (30d)
4

Description

Description

On iOS 16+ (New Architecture), long-pressing a <Text selectable> shows the edit menu ("Copy"), and the moment the finger is lifted the menu animates out and immediately back in. It is a ~100 ms blink on every release, on every selectable Text.

Cause: RCTParagraphComponentView.handleLongPress: does not check gesture.state. A UILongPressGestureRecognizer fires its action on Began and again on Ended (and on Changed when the finger moves). The second call re-runs [_editMenuInteraction presentEditMenuWithConfiguration:], and UIKit dismisses the presented menu before presenting the new one.

https://github.com/react/react-native/blob/v0.87.0/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm#L346-L353

- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
  if (@available(iOS 16.0, macCatalyst 16.0, *)) {
    CGPoint location = [gesture locationInView:self];
    UIEditMenuConfiguration *config = [UIEditMenuConfiguration configurationWithIdentifier:nil sourcePoint:location];
    if (_editMenuInteraction) {
      [_editMenuInteraction presentEditMenuWithConfiguration:config];
    }
  } else {
    // the legacy branch is guarded by `menuController.isMenuVisible`; the iOS 16 branch is not

Fix (verified, see below):

- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
  if (gesture.state != UIGestureRecognizerStateBegan) {
    return;
  }
  ...

Happy to open a PR if that helps.

Steps to reproduce
  1. Render <Text selectable>Some text</Text> in any screen (New Architecture, iOS 16+).
  2. Long-press the text until "Copy" appears.
  3. Lift the finger.

Expected: the menu stays. Actual: the menu disappears and reappears at touch-up.

Evidence: screen recording of the simulator at 20 fps, OCR of each frame for "Copy" (C = menu visible, . = not):

before: ....CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC..CCCCCCCCCCCCCCCCCCCCCCC....
after:  ....CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC....

The gap in the first line is the release (Maestro longPressOn, ~3 s hold). The second line is the same scenario with the one-line guard compiled in (built from source, ios.buildReactNativeFromSource in Expo).

React Native Version

0.86.2 (code unchanged in 0.87.0)

Affected Platforms

Runtime - iOS

Output of npx @react-native-community/cli info
System: macOS 26.2
Xcode: 26.4
iOS Simulator: iPhone 17 Pro
react-native: 0.86.2 (Expo SDK 57), New Architecture, Hermes
Stacktrace or Logs
n/a (visual)
MANDATORY Reproducer

Any <Text selectable> on iOS 16+ with the New Architecture reproduces it; the bug is fully explained by the source above (the action handler is invoked for every gesture state).

Screenshots and Videos

Frame-by-frame OCR trace above.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Open packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm and inspect handleLongPress:. Reproduce the selectable Text long-press on iOS 16+ with the New Architecture, then verify that the edit menu remains visible after release without flickering.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, objective-c, react-native
Domain
mobile
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.