I want to change some or all of the text attribute of a rich UITextView (iOS 6) and allow the user to undo the change.
After reading the NSUndoManager documentation , I tried the first method:
"Simple undo" based on a simple selector with a single object argument.
I expected the undo operation to be as simple as:
Declare this method:
- (void)setAttributedStringToTextView:(NSAttributedString *)newAttributedString {
NSAttributedString *currentAttributedString = self.textView.attributedText;
if (! [currentAttributedString isEqualToAttributedString:newAttributedString]) {
[self.textView.undoManager registerUndoWithTarget:self
selector:@selector(setAttributedStringToTextView:)
object:currentAttributedString];
[self.textView.undoManager setActionName:@"Attributed string change"];
[self.textView setAttributedText:newAttributedString];
}
}
Change the text in my UITextView by calling:
[self setAttributedStringToTextView:mutableAttributedString]
But after that, NSUndoManager says that it cannot cancel.
NSLog(@"Can undo: %d", [self.textView.undoManager canUndo]);
So I tried the second option:
"Invocation-based undo" which uses an NSInvocation object.
Declare this:
- (void)setMyTextViewAttributedString:(NSAttributedString *)newAttributedString {
NSAttributedString *currentAttributedString = [self.textView attributedText];
if (! [currentAttributedString isEqualToAttributedString:newAttributedString]) {
[[self.textView.undoManager prepareWithInvocationTarget:self]
setMyTextViewAttributedString:currentAttributedString];
[self.textView.undoManager setActionName:@"Attributed string change"];
[self.textView setAttributedText:newAttributedString];
}
}
and change the text with:
[self setMyTextViewAttributedString:mutableAttributedString]
After that, NSUndoManager also says that it cannot cancel.
Why?
Note that the user edits the UITextView when running code that changes the attribute text.
UITextInput. , NSAttributedString. ?
- (void)replaceRange:(UITextRange *)range withText:(NSString *)text
- . , ( , , ).