在 iPhone SDK 中使用 NSUndoManager 撤消/重做

发布于 2024-09-10 11:32:29 字数 524 浏览 6 评论 0原文

我一直在尝试使用 NSUndoManager 类在我的应用程序之一中设计撤消/重做功能,并发现一些设计困难。 在我的应用程序中,我只有一种方法,

-(IBAction) addLastBall:(Ball *)ball

因此,当用户在 UI 中选择一个按钮时,我将一个球对象添加到我的数组列表中。但是,我没有任何移除球的操作按钮,这是 UI 工作流程的设计,无法更改。 因此,为了实现撤消,我在 addLastBall 方法中调用了以下代码段。

[undoManager registerUndoWithTarget:self selector:@selector(removeBall:) object:ball];

执行此操作后,当用户尝试执行撤消时,将使用球对象调用removeBall 方法。目前一切都很好。 但是,我现在不确定如何处理重做部分,当用户尝试重做时,我不确定会调用哪个方法,因为我需要添加用户刚刚使用撤消操作删除的球对象。 任何见解都会非常有帮助。

非常感谢。

I have been trying to design the Undo/Redo functionality in one of my app using NSUndoManager class and seeing some design difficulties.
In my app, I just have one method

-(IBAction) addLastBall:(Ball *)ball

So, when a user chooses a button in the UI, I add a ball object to my array list. However, I don't have any action button to remove a ball, this is the design of the UI workflow and can't be changed.
So, to implement a undo I called the following piece of code inside the addLastBall method

[undoManager registerUndoWithTarget:self selector:@selector(removeBall:) object:ball];

After doing this, removeBall method gets called with the ball object when the user tried to perform the undo. All is good for now.
But, I am not sure how to handle the redo part now, when the user tries to redo, I am not sure which method would get called, because I need to add the ball object the user just removed using the undo operation.
Any insights would be very helpful.

Thanks so much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玩心态 2024-09-17 11:32:29

重做只是执行相应撤消执行时注册的撤消操作。因此,最直接的解决方案是简单地在 removeBall: 方法中注册撤消操作。

- (void)removeBall:(Ball *)ball {
    [undoManager registerUndoWithTarget:self 
                               selector:@selector(addLastBall:)
                                 object:ball];
    ...
}

请注意,有时使用 prepareWithInitationTarget: 注册撤消操作会更清晰:

[[undoManager prepareWithInvocationTarget:self] addLastBall:ball];

顺便说一下,请确保在 removeBall: 方法中将球的保留计数保持在零以上— 撤消管理器不会为您保留球,如果它被释放,那么撤消删除将会崩溃。

A redo simply performs the undo actions registered while the corresponding undo was executing. Therefore, the most straightforward solution is to simply to register an undo action in the removeBall: method.

- (void)removeBall:(Ball *)ball {
    [undoManager registerUndoWithTarget:self 
                               selector:@selector(addLastBall:)
                                 object:ball];
    ...
}

Note that it is sometimes clearer to useprepareWithInvocationTarget: to register undo actions:

[[undoManager prepareWithInvocationTarget:self] addLastBall:ball];

By the way, be sure to keep the retain count of the ball above zero in the removeBall: method — the undo manager will not retain the ball for you, and if it gets deallocated, then undoing the remove will crash.

吾家有女初长成 2024-09-17 11:32:29

没有调用 get 方法。
NSUndoManager 只是保存撤消操作的相反操作(重做),如果用户选择重做,则将完成该操作。

都是在NSUndoManager中实现的,所以你不用担心。
如果您希望在重做时调用您的方法,您应该考虑创建自己的撤消管理器,但我不建议您这样做。它可能会变得非常复杂,而且 NSUndoManager 可以完美地处理一切。

No method get's called.
The NSUndoManager simply saves the reverse of the undo operation (redo), that will be done, if the user choses redo.

It's all implemented in NSUndoManager, so you don't have to worry about it.
If you want your method to be called on redo, you should think about creating your own undo manager, but I wouldn't advice you to. It can get very complicated and besides, the NSUndoManager takes care of everything perfectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文