3

我正在使用 [undoManager registerUndoWithTarget::] 向撤消堆栈添加一些更改。但是,有时会发生,当在一个运行循环周期中将两个更改添加到同一组中时,它们会立即还原,这不是我想要的行为。我想将这两个更改分开,以便在撤消堆栈中有两个项目。如何正确实现这一点?使用 [NSObject performSelector: ] 在下一个运行循环周期中调用第二个撤消添加,或者其他什么?

谢谢。

4

1 回答 1

5

正如您所注意到的,默认情况下,NSUndoManager在一个运行循环周期中自动将撤消操作分组。但是,您可以更改该行为:-[NSUndoManager setGroupsByEvent:]如果您发送NO参数,将禁用自动分组。请注意,您需要确保在撤消管理器执行之前关闭所有组-undo-undoNestedGroup. 由于其他 Cocoa 类可能希望在不显式创建组的情况下注册撤消操作,因此您可以在注册撤消组之前禁用自动分组,在注册这些组后重新启用。

例如:

- (void)someMethod {
    NSUndoManager *undoManager = …; // for example, [[self window] undoManager]
    [undoManager setGroupsByEvent:NO];
    {
        [undoManager beginUndoGrouping];
        {
            [undoManager registerUndoWithTarget:modelObject selector:@selector(setString1:) object:[modelObject string1]];
            [modelObject setStringValue:newValue1];
            [undoManager setActionName:@"String 1 Change"];
        }
        [undoManager endUndoGrouping];


        [undoManager beginUndoGrouping];
        {
            [undoManager registerUndoWithTarget:modelObject selector:@selector(setString2:) object:[modelObject string2]];
            [modelObject setString2:newValue3];

            [undoManager registerUndoWithTarget:modelObject selector:@selector(setString3:) object:[modelObject string3]];
            [modelObject setString3:newValue3];

            [undoManager setActionName:@"Strings 2 and 3 Change"];
        }
        [undoManager endUndoGrouping];
    }
    [undoManager setGroupsByEvent:YES];
}

-someMethod中,三个更改应用于modelObject、 修改其string1string2string3属性。应用到的更改是撤消组的一部分,而对和string1的更改是另一个撤消组的一部分。两个组都包含在一个块中,其中撤消管理器没有将当前运行循环周期的默认撤消组中的所有操作分组。执行此方法后,第一个撤消操作撤消和更改,随后的撤消操作撤消应用于 的更改,前提是没有另一个撤消组包含它们。string2string3string2string3string1

我使用 C 块{}使这两个层次结构(不按事件和撤消组分组)清晰。

注意:NSUndoManager不是线程安全的

于 2013-06-03T09:39:11.013 回答