【发布时间】:2012-09-26 08:50:38
【问题描述】:
我想更改富 UITextView (iOS 6) 的部分或全部属性文本,并允许用户撤消更改。
看完NSUndoManager documentation,我尝试了第一种方式:
“Simple undo” based on a simple selector with a single object argument.
我希望撤消操作如此简单:
声明这个方法:
- (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];
}
}
通过调用更改我的 UITextView 中的文本:
[self setAttributedStringToTextView:mutableAttributedString];
但是在这样做之后,NSUndoManager 说它无法撤消。
NSLog(@"Can undo: %d", [self.textView.undoManager canUndo]);
// Prints: "Can undo: 0"
于是我尝试了第二种方式:
“Invocation-based undo” which uses an NSInvocation object.
声明:
- (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];
}
}
并使用以下命令更改文本:
[self setMyTextViewAttributedString:mutableAttributedString];
之后,NSUndoManager 也表示无法撤消。
为什么?
请注意,当触发将更改属性文本的代码时,用户正在编辑 UITextView。
一种解决方法是直接通过 UITextInput 协议方法替换文本。下面的方法还是挺方便的,但是我还没有找到 NSAttributedString 的等价物。我错过了吗?
- (void)replaceRange:(UITextRange *)range withText:(NSString *)text
这里建议的 hack 是模拟粘贴操作。如果可能的话,我宁愿避免这种情况(还没有理由,只是觉得太脏了,以后不回来咬我)。
【问题讨论】:
-
你确认
self.textView、self.textView.attributedText和self.textView.undoManager都不是nil了吗? -
是的。 self.textView.attributedText = newValue 实际上是在用户界面中更新的。 textView.undoManager 是类 WebThreadSafeUndoManager 的成员,并且是我的 viewController 的所有生命周期的同一个实例。
-
我注意到了同样的问题。我可以撤消一些操作,但不能撤消属性字符串替换。找不到解决方法(请参阅stackoverflow.com/questions/12501541/…)
标签: uitextview ios6 nsattributedstring nsundomanager uitextinput