15

I want to have to occasionally insert text into the UITextView text object. For example, if the user presses the "New Paragraph" button I would like to insert a double newline instead of just the standard single newline.

How can I go about such? Do i have to read the string from UITextView, mutate it, and write it back? Then how would I know where the pointer was?

Thanks

John Smith
  • 12,491
  • 18
  • 65
  • 111
  • possible duplicate of [replacing text in UITextView with NSUndoManager support](http://stackoverflow.com/questions/6419823/replacing-text-in-uitextview-with-nsundomanager-support) – Bo Persson Apr 26 '12 at 21:43

6 Answers6

33

Since the text property of UITextView is immutable, you have to create a new string and set the text property to it. NSString has an instance method (-stringByAppendingString:) for creating a new string by appending the argument to the receiver:

textView.text = [textView.text stringByAppendingString:@"\n\n"];
Martin Gordon
  • 36,329
  • 7
  • 58
  • 54
  • need to deal with fact that this might not be at end of the string. Some insertStringAtPoint-like function? What? – John Smith May 08 '10 at 01:52
  • 4
    Found it! it actually is insertString:atIndex: – John Smith May 08 '10 at 01:55
  • 9
    You might want to set textView.scrollEnabled = NO before updating textView.text; this prevents annoying scrolling to the end of text view – Ziga Kranjec Sep 15 '10 at 03:09
  • 1
    If the TextView has a lot of text, this could conceivably get quite slow as a lot of text must be copied every time. Would it be reasonable to replace the text view's text string with a MutableString and just cast it every time you do insert? – NHDaly Apr 19 '13 at 15:37
30

UITextview has an insertText method and it respects cursor position.

- (void)insertText:(NSString *)text

for example:

[myTextView insertText:@"\n\n"];
sudo
  • 1,648
  • 1
  • 20
  • 22
  • 4
    How is this not the accepted answer? This is the right way to do it without resorting to hacks. – NYC Tech Engineer Dec 18 '15 at 17:07
  • 1
    @sudo I don't know what i did wrong last time i tried this, but now it works! Thanks a lot! This saved my day (especially because it respects cursor position!!!!!!!!!!) – ParkerHalo Mar 30 '16 at 14:15
  • @NYCTechEngineer probably because the documentation is poor and inheritance further obscures things and unless it is explicitly mentioned somewhere, it is hard to find. I finally found the `insertText` docs (https://developer.apple.com/documentation/uikit/uikeyinput), but there are no links to it and nothing mentions it. – toraritte Jan 04 '18 at 14:51
9

Here's how I implemented it and it seems to work nicely.

- (void) insertString: (NSString *) insertingString intoTextView: (UITextView *) textView  
{  
    NSRange range = textView.selectedRange;  
    NSString * firstHalfString = [textView.text substringToIndex:range.location];  
    NSString * secondHalfString = [textView.text substringFromIndex: range.location];  
    textView.scrollEnabled = NO;  // turn off scrolling or you'll get dizzy ... I promise  

    textView.text = [NSString stringWithFormat: @"%@%@%@",  
      firstHalfString,  
      insertingString,  
      secondHalfString];  
    range.location += [insertingString length];  
    textView.selectedRange = range;  
    textView.scrollEnabled = YES;  // turn scrolling back on.  

}
Brian Moncur
  • 101
  • 1
  • 3
  • hi Brian, i have same problem here, i try your answer, i can insert the text, but the textview always jump into last line after inserting text, could you give me another help? – R. Dewi May 28 '12 at 01:52
  • @R.Dewi, set `textView.scrollEnabled=NO` before the change and change it back after. – Dustin Aug 02 '12 at 16:47
7

For Swift 3.0

You can append text by calling method insertText of UITextView Instance.

Example:

textView.insertText("yourText")
Parth Adroja
  • 13,198
  • 5
  • 37
  • 71
3

This is a correct answer!

The cursor position is also right.

A scroll position is also right.

- (void) insertString: (NSString *) insertingString intoTextView: (UITextView *) textView
{
    [textView replaceRange:textView.selectedTextRange withText:insertingString];
}
2
- (void)insertStringAtCaret:(NSString*)string {
    UITextView *textView = self.contentCell.textView;

    NSRange selectedRange = textView.selectedRange;
    UITextRange *textRange = [textView textRangeFromPosition:textView.selectedTextRange.start toPosition:textView.selectedTextRange.start];

    [textView replaceRange:textRange withText:string];
    [textView setSelectedRange:NSMakeRange(selectedRange.location + 1, 0)];

    self.changesDetected = YES; // i analyze the undo manager in here to enabled/disable my undo/redo buttons
}
Brad G
  • 2,528
  • 1
  • 22
  • 23