我想在替换NSTextView中的部分文本后实现撤消操作。我正在用以下代码替换部分文本
- (void)omeAction
{
NSString *fullString = [self.textView string];
NSRange selectedRange = [self.textView selectedRange];
NSString *selectedString = [fullString substringWithRange:selectedRange];
NSString *stringToReplace = ...;
[[self.textView textStorage] beginEditing];
[[self.textView textStorage] replaceCharactersInRange:selectedRange withString:stringToReplace];
[[self.textView textStorage] endEditing];
}
执行撤消时,我无法撤消文本替换
答案 0 :(得分:8)
来自Cocoa Text Architecture Guide: Text Editing – Text Change Notifications and Delegate Messages:
在实际更改文本时,必须确保文本系统的不同部分正确执行和记录更改。您可以使用shouldChangeTextInRange:replacementString:和didChangeText消息将每批潜在更改括起来。这些方法可确保发送适当的委托消息并发布通知。 ...
根据我的经验,这包括生成相关的撤消操作。
所以,你会这样做:
if ([self.textView shouldChangeTextInRange:selectedRange replacementString:stringToReplace])
{
[[self.textView textStorage] beginEditing];
[[self.textView textStorage] replaceCharactersInRange:selectedRange withString:stringToReplace];
[[self.textView textStorage] endEditing];
[self.textView didChangeText];
}
答案 1 :(得分:1)
首先我尝试解决undo和shouldChangeTextInRange:replacementString:做了诀窍。但是我发现insertText:replacementRange:具有相同的效果。
[self insertText:attributedString replacementRange:range];
或者:
if ([textView shouldChangeTextInRange:range replacementString:string]) { //string
[textStorage beginEditing];
[textStorage replaceCharactersInRange:range withAttributedString:attributedString];
[textStorage endEditing];
[textView didChangeText];
}