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 for when I programmatically set the text (e.g., for when I clear it, by setting it to @"").
Since only the firstResponder gets undo/redo events, I thought I'd simply use the UITextView's undoManager property to create my invocations. e.g.,
// 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 is not working. It:
- Introduces an empty item into the undo stack ("Undo")
- The "Undo Clear" gets added after that item (if I tap "Undo", I see "Undo Clear")
- Undo Clear and Redo Clear work, however, then I see "Undo Clear" again and it doesn't work from there on.
Any ideas? Am I approaching this wrong?
Update: It seems like I've figured out the empty undo item issue: it happens when I set the text of the UITextView after I've called prepareWithInvocationTarget. If I call it before, it doesn't happen. Funny thing is, the empty item isn't pushed onto the undo stack if I don't call prepareWithInvocationTarget (i.e., normally, when I set the text of a UITextView).