fix: clear text selection when user taps outside the view#46
Draft
haileyok wants to merge 1 commit into
Draft
Conversation
Adds a window-level UITapGestureRecognizer that fires when the user taps anywhere outside the component's bounds and clears selectedTextRange. The clear is deferred via dispatch_async so any in-flight edit-menu action (Copy / Define / Look Up / …) reads the live selection before we drop it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #36.
A non-editable, selectable
UITextViewdoes not auto-resign first responder on outside tap, so the text selection persists indefinitely. This adds a window-levelUITapGestureRecognizerthat fires on taps anywhere outside the component's bounds and clearsselectedTextRange.Notes on the design:
cancelsTouchesInView = NOso the tap still reaches whatever the user actually tapped (button, scroll view, etc.).gestureRecognizer:shouldReceiveTouch:filters via hit-test so the recognizer only fires when the touch is not a descendant ofself— taps inside our own text view are handled byUITextViewitself.selectedTextRange = nilis wrapped indispatch_async(dispatch_get_main_queue(), …)so any in-flight edit-menu action (Copy / Define / Look Up / Share / …) gets to read the live selection before we drop it. Without the defer, on iOS ≤15 the tap on aUICalloutBarbutton can race the action handler and Copy ends up with an empty pasteboard.didMoveToWindowand removed when the view leaves the window or is dealloc'd, so view recycling stays clean.Test plan
<UITextView selectable uiTextView>, tap empty space outside it — selection clears.<UITextView selectable uiTextView>on the same screen — selecting in one then tapping the other clears the first.ScrollView, scrolling does not clear the selection (it isn't a tap).FlatList) — no crash, no leaked recognizers.🤖 Generated with Claude Code