简体   繁体   English

如何使用NSTextview实现撤消

[英]How to implement undo with NSTextview

I want to implement undo action after replacing portion of text in an NSTextView. 我想在替换NSTextView中的部分文本后实现撤消操作。 I am replacing portion of text with following code 我用以下代码替换部分文本

- (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];
}

While performing undo I couldn't really undo the text replacement 执行撤消时,我无法撤消文本替换

From Cocoa Text Architecture Guide: Text Editing – Text Change Notifications and Delegate Messages : 来自Cocoa Text Architecture Guide:文本编辑 - 文本更改通知和委托消息

In actually making changes to the text, you must ensure that the changes are properly performed and recorded by different parts of the text system. 在实际更改文本时,必须确保更改由文本系统的不同部分正确执行和记录。 You do this by bracketing each batch of potential changes with shouldChangeTextInRange:replacementString: and didChangeText messages. 您可以使用shouldChangeTextInRange:replacementString:和didChangeText消息将每批潜在更改括起来。 These methods ensure that the appropriate delegate messages are sent and notifications posted. 这些方法可确保发送适当的委托消息并发布通知。 ...

In my experience, that includes generating the relevant undo operation. 根据我的经验,这包括生成相关的撤消操作。

So, you would do: 所以,你会这样做:

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

First I tried to solve undo and shouldChangeTextInRange:replacementString: did the trick. 首先我尝试解决undo和shouldChangeTextInRange:replacementString:做了诀窍。 However I found that insertText:replacementRange: had the same effect. 但是我发现insertText:replacementRange:具有相同的效果。

[self insertText:attributedString replacementRange:range];

Or: 要么:

if ([textView shouldChangeTextInRange:range replacementString:string]) { //string
  [textStorage beginEditing];
  [textStorage replaceCharactersInRange:range withAttributedString:attributedString];
  [textStorage endEditing];
  [textView didChangeText];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM