如何使用NSTextview实现撤消

时间:2014-08-31 10:05:45

标签: objective-c macos nstextview undo-redo

我想在替换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];
}

执行撤消时,我无法撤消文本替换

2 个答案:

答案 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];
}