View Full Version : modifying UITextView's text without gitter?

Jul 28, 2008, 05:39 PM
I'm trying to create a UITextView where, along with the keyboard, users could press buttons to insert text.

My first problem was that the view would always place the text selection cursor to the end of the text and then scroll all the way down.

I was able to fix this by keeping a record of the current selectionRange then using setSelectionRange to restore the previous state.

However, there is still a problem where it acts like all the text is deleted and then replaced. This causes it to scroll up then back down to where the selectionRange is located. In effect, it bounces around whenever the text is modified.

Is there any way to prevent this?
Obviously the iPhoneOS keyboard is perfectly capable of this, are whatever tools it uses to do that available to us?

-(void)addText:(string)in backIndex:(NSInteger)bi
string current = [editorTextView.text UTF8String]; //keep record of current text
NSRange selectionRange = editorTextView.selectedRange; // '' current selection

current.insert(selectionRange.location, in); //insert new text
selectionRange.location += in.length() - bi; //adjust selection accordingly

[editorTextView setText:[NSString stringWithUTF8String:current.c_str()]]; //apply the new text
[editorTextView setSelectedRange:selectionRange]; //apply the new selection

Jan 5, 2009, 06:32 PM
This was the first result that google displayed when I searched with the same problem, so I thought I'd post the solution I found.

Apparently using the undocumented setContentToHTMLString won't scroll around wildly. My problem is that the text I wanted to display as plain text HAS html in it. So I use a custom XString class and do a bit of replacing to maintain that formatting. This should get anyone started:

NSRange loc = contentView.selectedRange;
int rangeAdd = 0;
NSString* theText = [NSString stringWithString:[contentView.text substringToIndex:contentView.selectedRange.location]];

theText = [theText stringByAppendingString:@"Text to insert"];
rangeAdd = 11; // where do you want the selection cursor

theText = [theText stringByAppendingString:[contentView.text substringFromIndex:contentView.selectedRange.location]];

XString mod( [theText cString] );
mod.Replace( "<", "&l--t;" );
mod.Replace( ">", "&g--t;" );

mod.Replace( "<", "&lt;" );
mod.Replace( ">", "&gt;" );

// also sanitize line feeds- windows, old macintosh, unix/new macintosh
// otherwise converting from HTML back to text may cause you headaches
if ( mod.Find("\r\n") ) {
mod.Replace( "\r\n", "\n" );
} else {
mod.Replace( "\r", "\n" );

mod.Replace( "\n", "<br>" );

theText = [NSString stringWithCString:mod.CString()];

loc.location += rangeAdd;

[contentView setContentToHTMLString:theText];
[contentView setSelectedRange:loc];

Sep 23, 2010, 06:19 AM
Try setting the scrollEnabled property of your UITextView to FALSE before changing the text programmatically, then setting it back to TRUE after (and after you fix the selectedRange property, if you need to). This fixed the jumpiness in my UITextView, and didn't require messing around with trying to pass off your string as an HTML string.

(for anybody that has this issue and stumbles on this post :)