Change Tracking and Undo Operations
The saveless-model feature of the UIDocument
class ensures that document data is automatically saved at frequent intervals, relieving users of the need to explicitly save their documents. UIDocument
implements much of the behavior for the saveless model, but a document-based application must play its own part to make the feature work.
How UIKit Saves Document Data Automatically
The saveless model implemented by the UIKit framework for documents has two main parts: a mechanism for marking a document as needing to be saved and a variable period for when the framework checks that flag. Periodically, UIKit calls the hasUnsavedChanges
method of a UIDocument
object and evaluates the returned value. If the value is YES
, it saves the document data to the document file. The period between checks of the hasUnsavedChanges
value varies according to several factors, including the rate of input by the user.
A document-based application sets the value returned by hasUnsavedChanges
indirectly, either by implementing undo and redo or by tracking changes to the document. Change tracking requires the application to call the updateChangeCount:
method, passing in UIDocumentChangeDone
(a constant of type UIDocumentChangeKind
). When an application registers an undo action and then sends undo
or redo
messages to the document’s undo manager, UIDocument
calls updateChangeCount:
on its behalf.
Because giving users the ability to undo and redo changes can be a differentiating feature, that approach is recommended for most applications.
Implementing Undo and Redo
You can implement undo and redo operations in your application by following the procedures and recommendations in Undo Architecture. Note that UIDocument
defines an undoManager
property. You can get the default NSUndoManager
object by accessing this property, or you can assign your own NSUndoManager
object to it. The undo manager must be associated with the UIDocument
object through the property in order to enable change tracking and thus automatic saving of document data.
Listing 5-1 illustrates an implementation of undo and redo for a text field.
Listing 5-1 Implementing undo and redo for a text field
- (void)textFieldDidEndEditing:(UITextField *)textField { |
self.undoButton.enabled = YES; |
self.redoButton.enabled = YES; |
if (textField.tag == 1) { |
[self setLocationText:textField.text]; |
} |
// code for other text fields here.... |
} |
- (void)setLocationText:(NSString *)newText { |
NSString *currentText = _document.location; |
if (newText != currentText) { |
[_document.undoManager registerUndoWithTarget:self |
selector:@selector(setLocationText:) |
object:currentText]; |
_document.location = newText; |
self.locationField.text = newText; |
} |
} |
- (IBAction)handleUndo:(id)sender { |
[_document.undoManager undo]; |
if (![_document.undoManager canUndo]) self.undoButton.enabled = NO; |
} |
- (IBAction)handleRedo:(id)sender { |
[_document.undoManager redo]; |
if (![_document.undoManager canRedo]) self.redoButton.enabled = NO; |
} |
Implementing Change Tracking
To implement change tracking instead of implementing undo/redo, call the updateChangeCount:
method on the UIDocument
object at the appropriate points in your code. Just as when you register an undo action, it’s typically at the point where you update the document’s model object with data the user has just entered. The parameter passed in should be a UIDocumentChangeDone
constant.
Listing 5-2 shows how you might call updateChangeCount:
from within a UITextViewDelegate
method that is called when a change is made in a text view.
Listing 5-2 Updating the change count of a document
-(void)textViewDidChange:(UITextView *)textView { |
_document.documentText = textView.text; |
[_document updateChangeCount:UIDocumentChangeDone]; |
} |
Copyright © 2012 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2012-09-19