software-mansion / software-mansion/react-native-enriched-html
[iOS] Dragging a text selection aborts - TextBlockTapGestureRecognizer desyncs RCTSurfaceTouchHandler's touch registry
@kacperzolkiewski is already working on this.
Since Jul 20, 2026.
- Dominant language
- C
- Stars
- 1.4k
- Forks
- 66
- Avg merge
- 4d 19h
- Merged PRs (30d)
- 11
Description
Describe the bug
TextBlockTapGestureRecognizer reconfigures touch delivery on the UITextView for every touch, which desyncs React Native's RCTSurfaceTouchHandler touch registry and aborts the app when dragging a text selection.
In its initialiser (ios/utils/TextBlockTapGestureRecognizer.mm):
self.cancelsTouchesInView = YES;
self.delaysTouchesBegan = YES;
self.delaysTouchesEnded = YES;
for (UIGestureRecognizer *gr in _input->textView.gestureRecognizers) {
[gr requireGestureRecognizerToFail:self];
}
delaysTouchesBegan = YES withholds touchesBegan: from the view hierarchy until this recognizer resolves. RCTSurfaceTouchHandler (a recognizer on the RN root view) then receives touchesMoved: for a touch it never registered in touchesBegan:, and trips its assert:
auto iterator = _activeTouches.find(touch);
RCTAssert(iterator != _activeTouches.end(), @"Inconsistency between local and UIKit touch registries");
Crash is SIGABRT, no JS error:
0 CoreFoundation __exceptionPreprocess + 164
1 libobjc.A.dylib objc_exception_throw + 88
3 <app>.debug.dylib -[RCTSurfaceTouchHandler _updateTouches:] + 528
4 <app>.debug.dylib -[RCTSurfaceTouchHandler touchesMoved:withEvent:] + 124
5 UIKitCore -[UIGestureRecognizer _componentsChanged:withEve
6 UIKitCore -[UITouchesEvent _sendEventToGestureRecognizer:] + 488
12 UIKitCore -[UIWindow sendEvent:] + 3540
13 UIKitCore -[UIApplication sendEvent:] + 408
The abort itself is debug-only (RCTAssert compiles out in release), but the touch registry is equally wrong in release. RN just silently skips the touch update instead of reporting it. This leads to crashes in downstream code.
Separately, the requireGestureRecognizerToFail: loop gates UITextView's own selection recognizers behind this one on every touch, which makes selection dragging occasionally buggy.
To Reproduce
- Run a debug build of an app rendering
<EnrichedTextInput>withdefaultValuecontaining some styled content, e.g.<html><p>some <s>struck</s>text</p><blockquote>quoted text</blockquote></html>. - Long-press in the text to start a selection.
- Drag the selection handle across a styled region, e.g. so its end extends across the strikethrough.
- You might have to repeat step 3 a few times, or even restart the app to get it to trigger.
- App aborts with
Inconsistency between local and UIKit touch registries.
We first found this reliably reproducible by dragging a selection that ends inside a blockquote, but have since hit it with strikethroughs too, so it is not specific to any one style. Plain-text drags did not reproduce the issue.
Expected behavior
Dragging a text selection should never crash, and the recognizer should not alter touch delivery.
Screenshots
N/A. The app aborts with no UI.
Device (please complete the following information):
- Device: IPhone 16 Plus
- OS: iOS 26.5.2 (23F84)
- Version:
react-native-enriched-html1.0.0,react-native0.85.3, Expo SDK 56, New Architecture
Additional context
We patched it locally by restoring stock UIKit touch delivery and dropping the loop:
self.cancelsTouchesInView = NO;
self.delaysTouchesBegan = NO;
self.delaysTouchesEnded = NO;
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.