Undo and Redo

This topic is quite difficult to digest, but after few exercises you should be able to manage it.

When you work with an application, it usually happens that, after applying some edits to your data, you realize that the final result is not what you were expecting. So, you wish to go back and remove what you have done. I believe you are familiar with the Undo and Redo items in the Edit menu of your Mac. But, how can you implement these functionalities in your application?

Cocoa and Cocoa Touch use an intelligent approach to manage this. To understand it, I have to introduce the concept of NSInvocation. An NSInvocation is an object containing all the elements of an Objective-C message: a target, a selector, some arguments, and the return value. Each of these elements can be set directly and the return value is set automatically when the NSInvocation object is dispatched. NSInvocation works together with the NSUndoManager to make the Undo/Redo mechanism possible.

When you apply an edit onto your data and you want to be able to undo that edit, you need to prepare (coding) the inverse operation corresponding to that particular edit. Then, you pack this inverse message (including selector, arguments and return value) in an NSInvocation object and forward it to the NSUndoManager. This will store this object in a stack and wait for the user action. Indeed, there are two stacks: the Undo Stack and the Redo Stack and their scope is very similar. The management of the two stacks is assigned to NSUndoManager and you don’t need to take care of it. When you undo some operation, NSUndoManager removes from the Undo Stack that operation and adds it to the Redo Stack. If you redo that operation, this time the NSUndoManager removes it from the Redo Stack and adds it to the Undo Stack.

Let’s look at the details and how to code it. Suppose you are writing a simple calculator with a plus and minus operations:

You want to be able to undo and redo each of these operations after you apply them to your data. When you start your application, an NSUndoManager object is created for you with no costs. In reality, if you are writing a document-based application in Cocoa, an NSUndoManager is created automatically. In the other cases (iPhone included), you have to create it explicitly.

You usually need only an NSUndoManager for each application. To register the above two methods to the NSUndoManager mechanism, you do the following:

The undoManger method (lines 3 and 4) is defined in the NSDocument, NSResponder, NSManagedObjectContext and WebView classes. Please, refer to the documentation of these classes for details.

The trick is at the lines 4 and 15. There, you register to the Undo/Redo mechanism the opposite operation to your current edit.

You can also change the label of the Undo and Redo operation using the

So, you can add this line after line 4:

Once implemented, you will have in the edit menu “Undo Add”.




(Visited 100 times, 1 visits today)