How can I replace text in UITextView with NSUndoManager support?

前端 未结 4 557
清歌不尽
清歌不尽 2021-02-06 01:00

I want to be able to replace some text in an UITextView programatically, so I wrote this method as an UITextView category:

- (void) replaceCharactersInRange:(NSR         


        
相关标签:
4条回答
  • 2021-02-06 01:01

    After having stumbled over this issue and getting grey hair of it, I finally found a satisfying solution. It's a bit tacky, but it DOES work like a charm. The idea is to use the working copy&paste support that UITextView offers! I think you might be interested:

    - (void)insertText:(NSString *)insert
    {
        UIPasteboard *pboard = [UIPasteboard generalPasteboard];
    
        // Clear the current pasteboard
        NSArray *oldItems = [pboard.items copy];
        pboard.items = nil;
    
        // Set the new content to copy
        pboard.string = insert;
    
        // Paste
        [self paste: nil];
    
        // Restore pasteboard
        pboard.items = oldItems;
        [oldItems release];
    }
    

    EDIT: Of course you can customize this code to insert text at any position in the text view. Just set the selectedRange before calling paste.

    0 讨论(0)
  • 2021-02-06 01:05

    There is actually no reason for any hacks or custom categories to accomplish this. You can use the built in UITextInput Protocol method replaceRange:withText:. For inserting text you can simply do:

    [textView replaceRange:textView.selectedTextRange withText:replacementText];
    

    This works as of iOS 5.0. Undo works automatically and there are no weird scrolling issues.

    0 讨论(0)
  • 2021-02-06 01:05

    Shouldn't it be

    [[self.undoManager prepareWithInvocationTarget:self] replaceCharactersInRange:NSMakeRange(range.location, newText.length) 
                                                                       withString:[self.text substringWithRange:range]];
    

    And you probably can remove the mutable string and just do,

    self.text = [self.text stringByReplacingCharactersInRange:range withString:newText];
    
    0 讨论(0)
  • 2021-02-06 01:25

    I've been having trouble with this for a long time. I finally realized that you have to make sure you register the undo operation BEFORE doing any changes to your text storage.

    0 讨论(0)
提交回复
热议问题