I want to have an insert tab button for my UITextView so that users be able to insert a tab at beginning of the current line. No matter where the cursor is in the line, the tab should be inserted at the beginning of the line, and after that the cursor must go to the end of the line.
Is it possible ?
I have no luck with
positionFromPosition:inDirection:offset:
andcharacterRangeByExtendingPosition:inDirection:
.But this works fine for me:
UPD: the code above is tested on iOS7 and earlier. And can no longer work with iOS9. Actually, I have some bugs in my text-editing app running on iOS9-devices. I'll update my answer after fixing my app.
UITextView implements the UITextInput protocol, which has a whole bunch of methods for determining positions of text. I'm not sure about this, but perhaps you can call:
selectedTextRange
to get the caret position.positionFromPosition:inDirection:offset:
withUITextLayoutDirectionLeft
to find the range to the start of the current line. (This I'm not sure about; maybecharacterRangeByExtendingPosition:inDirection:
would work better?)textRangeFromPosition:toPosition:
to get a range for the start of the lin.replaceRange:withText:
to insert a tab.There might be other methods in that protocol that would let you figure that out if that doesn't work.
Edit: Seems that UITextView only implements UITextInput as of iOS 5. If you're targeting before that, I'm not sure what to suggest.
I'll add the code that I've been using to move the cursor to the beginning of the line (
homeTap
) as it addresses some of the comments within @zxcat's answer, regarding the cursor being moved to the beginning of previous line rather than the current line:Specifically, I add
halfLineHeight
torect.origin.y
to make sure the result fromclosestPositionToPoint
is for the current line.