I want to be able to replace some text in an UITextView programatically, so I wrote this method as an UITextView category:
- (void) replaceCharactersInRange:(NSRange)range withString:(NSString *)newText{
self.scrollEnabled = NO;
NSMutableString *textStorage = [self.text mutableCopy];
[textStorage replaceCharactersInRange:range withString:newText];
//replace text but undo manager is not working well
[[self.undoManager prepareWithInvocationTarget:self] replaceCharactersInRange:NSMakeRange(range.location, newText.length)
withString:[textStorage substringWithRange:range]];
NSLog(@"before replacing: canUndo:%d", [self.undoManager canUndo]); //prints YES
self.text = textStorage;
NSLog(@"after replacing: canUndo:%d", [self.undoManager canUndo]); //prints NO
if (![self.undoManager isUndoing])[self.undoManager setActionName:@"replace characters"];
[textStorage release];
//new range:
range.location = range.location + newText.length;
range.length = 0;
self.selectedRange = range;
self.scrollEnabled = YES;
}
It works but NSUndoManager stops working (it seems to be reset) just after doing self.text=textStorage
I have found a private API: -insertText:(NSString *)
that can do the job but who knows if Apple is going to approve my app if I use it. Is there any way to get text replaced in UITextView with NSUndoManager Support? Or maybe I am missing something here?
replaceRange:withText
will do the job and UITextInput protocol is indeed available from 3.2 but UITextView didn't adopt it until 5.0. So this answer only will work on OS5.0 and above – Perkins