NSUndoManager 和 replacing/skipping 撤消步骤

NSUndoManager and replacing/skipping undo steps

有什么方法可以告诉 undoManager 在某些情况下撤消步骤已经在编辑发生之前提交了吗?

我有一个应用程序可以自动将某些字符串替换为对应的大写字母。问题是,这必须在 textStorage 中自动完成,因此当撤消编辑时,文本仍保持大写。

我已经为相关操作编写了自定义撤消状态,这些状态是在 NSTextView shouldChangeTextInRange:

中创建的

例如:

[[self.undoManager prepareWithInvocationTarget:self] 
       replaceCharactersInRange:
             NSMakeRange(affectedCharRange.location + affectedCharRange.length, string.length + 1) withString:string
];

我希望 undoManager 忽略编辑后将要接收的撤消步骤。

一种方法是使用 [self.undoManager disableUndoRegistration]; 禁用 NSUndoManager 记录撤消步骤。然后,操作完成后,您可以再次启用它[self.undoManager enableUndoRegistration]

这似乎是一种有点危险的方法,因为它真的会使您的撤消堆栈变得混乱。

我通过在 NSTextView 撤消注册之前执行额外的撤消步骤解决了这个问题:

[self.undoManager registerUndoWithTarget:self handler:^(id _Nonnull target) {
    [self replaceCharactersInRange:undoStringRange withString:undoString];
}];

不过,重做可能会造成伤害,因为整个受影响的字符串可能不会在文本视图的内部方法中注册。