iOS place cursor after word in UITextView - ios

I have a string in a UITextView.
NSString *str = #"Hello world. What #are you #doing ?"
When I tap on the UITextView the cursor goes where I tap on the string. But I need that, suppose I tap on any character of that textview, the cursor will automatically goes to the end of that word. For e.g, I tap on the character "e" in "Hello", then the cursor will place after "Hello".
How can I do this?

You have to understand the concept and underlying structure of a touch device.
Let me explain.
When you have a textfield/ textview, inside a view and your keyboard is not showing ie. textfield is inactive. The superview might have any number of gesture recognisers other than the textfield.
Hence the OS just detects the touch which will make the UI element become firstResponder, or rather Active.
After the textfield is active, OS recognises that the other gesture pattern will come into play in this moment. And in this moment you can tap in any position (or Long tap) and then place ur cursor at any character you want.
Hope you could understand.

this should be the default behavior of textview. You not need to do any additional setup for that! If you will long press then only your cursor go at particular character otherwise it will go to end of the word. this is the default behavior.

Related

Does NSAttributedString's enumerateAttribute method's block pass character ranges or glyph ranges?

tl;dr: if I call NSAttributedString's enumerateAttribute:inRange:options:usingBlock: method, does the range argument to the block pass a glyph range or a character range?
I have a text view in my app that needs to behave like Notes.app in that when it's not in edit mode, it should show hyperlinks (and they should be tappable), and it should enter edit mode on tap. UITextView doesn't show hyperlinks when editable, but if it's not editable then it won't gain focus on tap by itself. Until iOS 11 this could be solved by using a UITapGestureRecognizer on the text view to trigger editing, but it seems something (maybe with drag and drop?) changed how gesture recognizers work with UITextView (rdar://33009324).
My new and improved solution is a custom UIGestureRecognizer that fires if it sees a tap that is not on a hyperlink, and making all other recognizers on the text view to require it to fail before firing. This is implemented by processing touches, getting their location in the text view, getting the character index for that point, enumerating the NSLinkAttributeName in the text view's textStorage, and checking if my character index overlaps with any of the hyperlinks I get back. If so, then the user tapped on a link, and this recognizer fails.
However, if the character index of the tap does intersect with a link, I need to make sure the tap actually intersects with the link's rect, because it could be that this link is the last thing in the text view's content and the touch is actually below the last line of text. I can do this by getting the rect for the range of the link and checking if it intersects with my touch point. I can use boundingRectForGlyphRange:inTextContainer: for this, but this leads to my question: is the range I have for the link a character range or a glyph range? Do I need to convert it via glyphRangeForCharacterRange:actualGlyphRange: first?
It returns a character range. NSAttributedString doesn't know anything directly about glyphs. Converting characters to glyphs can't happen until layout is performed, and NSAttributedString doesn't include layout information. For example, an NSAttributedString doesn't know how wide an area it will be drawn into, and without that, you can't know where line breaks will be, and without that you can't decide where to put ligatures.
NSAttributedString knows nothing glyphs, and yes, if you need to know where the glyphs are in a TextKit stack such as that of a UITextView, you ask the layout manager to convert for you.

Allow cursor selection anywhere in UITextView

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.

UITextView responding unexpected to accessibility voice over

Currently I am walking through my whole iOS app to optimize it for accessibility voice over. When it comes to the UITextView, which I subclassed, voice over is not acting like I thought it would. My UITextView subclass is only changing a path's color on the superview's layer in becomeFirstResponder and resignFirstResponder. So nothing special on my UITextView subclass that could interfere with accessibility.
As long as there is no text in the UITextView it is acting as expected. Voiceover tells me that it is a text field and that I can double tap it to edit. But as soon as there is text in the UITextView, the only thing voice over tells me, is the value of the UITextView. Voice over doesn't tell me anymore that this is an editable text field.
Am I doing something wrong? Why is it acting like that?
I do appreciate any help!
If you didn't edit any accessibility hints or labels for the text field it should act accordingly. If selected it should say:
It is a text field
If you are editing it
The editing mode you are in
The value of the text field (nil if empty)
Where the cursor is
Then while you type it says the letters you are entering as you enter them. When you hit space or enter it should say the word you just typed. As long as your text field is exhibiting these behaviors you should be fine.
Tip: if you want to know how accessibility elements should act, try using a native iOS app with accessibility turned on and compare it with your app.

Adding tap gesture to the second part of string after full stop iOS

I have a label on a UIView. The text of the label is "All 100 entities selected. Select all from server" I know how to handle a tap gesture on the whole label. However, in this case, I need the tap gesture to work only if the user taps on 'Select all from server' part of the string. The portion of the string before and after the full stop can be of variable length.
I have come across TTTAttributedString but am wondering whether its usage is appropriate for my problem.

why does GestureRecognizer not work on textview first time?

I have a textView to input some text or emotion. so I make another button to change the keyboard to custom emotion view, and I also use tap GestureRecognizer for when I want to change back to keyboard.
I found every time I need to touch the button twice, the tap GestureRecognizer can work well. I thought and search long time but no result, finally I fix it. I think some one will meet the same question, so I shared it below.
because my add tap gesture recognition 's code is in init code, but when I tap textview, keyboard was pop up, the textview's position was changed too, so the init tap gesture recognition code isn't work now.
I fix it with add tap gesture recognition delay 0.3 s.

Resources