I have a single UITextView
, which lets you write multiple lines of text.
How can I let users select letters in between words without a long press?
Currently, when using the touchscreen to select characters between a word, the cursor either goes the start or end of the word:
Example: clicking on 'c' moves cursor to end of word
Example: clicking on 'a' moves cursor to start of word
Desired cursor behavior: Selection anywhere in text
The feature of allowing text selection anywhere (without the long press + magnifying glass) is found in many code editor apps for iOS, such as Coda and Pythonista.
This is not a difficult challenge to achieve.
I will preface that the issue with this approach is consistency. Remember that your users are using their fingers, rather than stilii. A finger has a large surface area, and hitting a precise pixel zone is quite difficult, especially with small text. I would suggesting playing not in the simulator, where you have a precise pointing device, but on a device.
The first challenge is to disable the default tap behavior or UITextView
. This is not a difficult task - you can either "attack" the problem at the touchesBegan:withEvent:
level, where you would have to understand what these touches are (single tap vs. pan vs. long press), or at the gesture recognizer level, where you'd disable the private gesture recognizers of the text view which specifically handle cursor movement in case of tap (vs the other touch types). I've done the latter for various projects, and it is possible. You could also try the approach without disabling the default behavior, but then the cursor may flicker. Test and decide.
Now to achieve what you need. Obtain the point of touch somehow (either using UIResponder
API or gesture recognizer). Remember, the text view is a scroll view which includes a large subview where the content is drawn into. You have to convert this touch point, from the text view coordinate system, to the internal view's coordinate system using the convertPoint:
API. Once you have that, you can use the text view's layout manager to obtain the character index at the point of touch:
NSUInteger chIdx = [self characterIndexForPoint:touchPoint inTextContainer:self.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
You can use this index to set the cursor of the text view using the selectedRange
property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With