Undo / redo with UITextView (iOS / iPHone)

I have a view where a UITextView always has focus. What I want to do is extend the built-in undo / redo behavior to support undo / redo when I programmatically set the text (for example, when I clear it by setting it to @ "").

Since only firstResponder receives cancel / redo events, I thought I was just using the UITextView undoManager property to create my calls. eg,

 // Before clearing the text ... [[self.myTextView.undoManager prepareWithInvocationTarget: self] undoClear: self.myTextView.text];  [self.myTextView.undoManager setActionName: @ "Clear"];  // ... - (void) undoClear: (NSString *) textToRestore {self.myTextView.text = textToRestore;  if ([self.myTextView.undoManager isUndoing]) {// Prepare the redo.  [[self.myTextView.undoManager prepareWithInvocationTarget: self] undoClear: @ ""];  }} 

Unfortunately this does not work. It:

  • Inserts an empty item into the cancel stack ("Undo")
  • After this item, “Undo Clear” is added (if I click Undo, I see “Undo Clear”)
  • Cancel Clear and Repeat Clear work, however, I see “Cancel Clear” again, and it does not work from there.

Any ideas? Am I approaching this wrong?

Update: Looks like I figured out the issue with the empty release: this happens when I set the text to a UITextView after I call prepareWithInvocationTarget. If I call earlier, this will not happen. Funny, an empty element is not pushed onto the cancel stack unless I call prepareWithInvocationTarget (i.e., usually when I set the text to a UITextView).

+3
source share
3 answers

OK, it turned out:

C # 1 issue is listed in the update to my original post.

Issues # 2 and # 3 were just me, using NSUndoManager incorrectly. My final unClear method (which is called to cancel, looks like this:

  - (void) undoClear: (NSString *) textToRestore
 {   
     NSString * textBackup = [self.myTextView.text copy];

     self.myTextView.text = textToRestore;

     if ([self.myTextView.undoManager isUndoing])
     {
         // Prepare the redo.
         [[self.myTextView.undoManager prepareWithInvocationTarget: self] undoClear: @ ""];     
     }
     else if ([self.myTextView.undoManager isRedoing])
     {
         [[self.myTextView.undoManager prepareWithInvocationTarget: self] undoClear: textBackup];
     }

     [textBackup release];
 } 

Now it works as it should.

+3
source

You can change your text view to any text you want and save stacks of undo and redo memory. self.content - UITextView.

-(void) yourClearAllButtonIsPressed { [[self.content.undoManager prepareWithInvocationTarget:self] undoClear:self.content.text]; [self.content setText:@""];//Or something else you want to change your textview to } } 

// only one, my method that I created

 -(void) undoClearBlablabla:(NSString*) text { [[self.content.undoManager prepareWithInvocationTarget:self] undoClear:self.content.text]; [self.content setText:text]; } 
+1
source

I do not blame how many text fields you work, although textBackup not saved in prepareWithInvocationTarget: How is this still on the Undo stack a bit later? It seems that he can still be there after the first, although not after the second or after the startup pool.

0
source

All Articles