Cocoa 我如何才能成为NSUndoManager';s撤消/重做操作名称是否正常工作?
我在学可可,而且我工作起来没有太多麻烦。但是setActionName:方法让我感到困惑。这里有一个简单的例子:一个玩具应用程序,其窗口包含一个文本标签和两个按钮。按下“打开”按钮,标签上显示“打开”。按下“关闭”按钮,标签变为“关闭”。以下是两个相关的方法(我为应用程序编写的唯一代码): 以下是我的期望:Cocoa 我如何才能成为NSUndoManager';s撤消/重做操作名称是否正常工作?,cocoa,undo,nsundomanager,Cocoa,Undo,Nsundomanager,我在学可可,而且我工作起来没有太多麻烦。但是setActionName:方法让我感到困惑。这里有一个简单的例子:一个玩具应用程序,其窗口包含一个文本标签和两个按钮。按下“打开”按钮,标签上显示“打开”。按下“关闭”按钮,标签变为“关闭”。以下是两个相关的方法(我为应用程序编写的唯一代码): 以下是我的期望: 我点击“打开”按钮 标签改为“开” “编辑”菜单中有“撤消打开标签”项 我点击那个菜单项 标签改为“关闭” “编辑”菜单中的“重做打开标签”项 事实上,除了上一个,所有这些都像我期望的那
- 我点击“打开”按钮
- 标签改为“开”
- “编辑”菜单中有“撤消打开标签”项
- 我点击那个菜单项
- 标签改为“关闭”
- “编辑”菜单中的“重做打开标签”项
我误解了什么?我如何才能让这些菜单项以我希望的方式显示?在查看了一些示例代码后,我能够通过在每个方法中的setActionName:调用中添加一个条件来解决这个问题,如下所示:
if (![[self undoManager] isUndoing])
[[self undoManager] setActionName:@"Turn On Label"];
我会给任何人一个正确的答案,谁能解释为什么NSUndoManager需要我这么做 因为turnOnLabel:方法可以通过三种可能的方式调用: 1) 当所选控件关联的控件正在执行其目标/操作序列时(即,NSUndoManager isUndoing和isRedoing方法将返回NO) 2) 执行撤消操作时,NSUndoManager实际上正在调用turnOnLabel:方法(即isUndoing=YES和isRedoing=NO) 3) 当您执行重做操作时,NSUndoManager实际上正在调用turnOnLabel:方法(即isUndoing=NO和isRedoing=YES)
isUndoing isRedoing操作
-------------------------------------------------
0打开标签
0 1打开标签
10关闭标签
1 1
记住:重做时,代码必须为“撤消”菜单项设置操作名。
当您撤消或重做时,重做菜单项中的actionName将自动设置。
setActionName:
仅更改撤消菜单项。重做菜单项actionName是自动的
当您开始时设置操作名:
当时![[self-undoManager]isUndoing]
,此操作名将转到撤消菜单项。当您选择撤消([[self undoManager]isUndoing]==YES
,您不设置任何操作名)撤消管理器自动将此操作名设置为重做菜单项,将上一个撤消操作名设置为撤消菜单项。然后选择重做时,仍需传递actionName才能转到“撤消”菜单项
换句话说:只有在代码未撤消时才需要设置ActionName(但必须在最初调用或重做时设置)。Clarence感谢您的回答。我理解你所说的,但我不明白为什么setActionName会有不同:是在撤消、重做还是第一次执行时调用它。无论哪种方式,据我所知,正在向撤消/重做堆栈中添加或从中删除一个操作,并且该操作应该具有相同的名称。我在这里只提到
setActionName:
的功能,而不是redActionName:
或undoActionName:
if (![[self undoManager] isUndoing])
[[self undoManager] setActionName:@"Turn On Label"];
isUndoing isRedoing Action
-------------------------------------------------
0 0 Turn On Label
0 1 Turn On Label
1 0 Turn Off Label
1 1 <impossible state>