J'ai un document qui a une réunion. Lorsque j'initialise la réunion, je définis undoManager pour pointer sur undoManager du document. De même, ma réunion a des participants (liste de personne). Chaque objet Person pointe simplement vers undoManager de ma réunion, qui est à son tour un pointeur sur le Document.NSUndoManager - Annuler Le bouton ne s'affiche pas
Mon annulation pour ajouter et supprimer des participants à la réunion fonctionnait jusqu'à ce que je commence à observer les valeurs de clé pour les attributs de la personne.
Des idées sur ce que je fais mal? Lorsque j'ajoute et supprime un participant, le bouton Annuler ne s'active pas. De même, lorsque je modifie le nom/débit de la personne, le bouton Annuler n'apparaît pas.
Document.m
- (id)init
{
self = [super init];
if (self) {
self.meeting = [[Meeting alloc] init];
self.meeting.undoManager = self.undoManager;
meeting.h ---
@property (nonatomic, retain) NSUndoManager *undoManager;
meeting.m
- (void)changeKeyPath:(NSString *)keyPath
ofObject:(id)obj
toValue:(id)newValue {
// setValue:forKeyPath: will cause the key-value observing method
// to be called, which takes care of the undo stuff
[obj setValue:newValue forKeyPath:keyPath];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
// NSNull objects are used to represent nil in a dictionary
if (oldValue == [NSNull null]) {
oldValue = nil;
}
[[self.undoManager prepareWithInvocationTarget:self] changeKeyPath:keyPath
ofObject:object
toValue:oldValue];
// Notify the undoManager
self.undoManager.actionName = @"Edit";
}
- (void)startObservingPerson:(Person *)person {
// TODO: Understand if I need something for context
[person addObserver:self
forKeyPath:@"name"
options:NSKeyValueObservingOptionOld
context:nil];
[person addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionOld
context:nil];
}
- (void)stopObservingPerson:(Person *)person {
[person removeObserver:self forKeyPath:@"name"];
[person removeObserver:self forKeyPath:@"rate"];
}
-(void) insertObject:(id *)object inAttendeeListAtIndex:(NSUInteger)index {
[(Person *)object setMeeting:self];
// Enable undo capabilities for edits to the name/rate
[self startObservingPerson:(Person *)object];
// insert the object/person
[self.attendeeList insertObject:(Person *)object atIndex:index];
//
// configure the undo for the insert
[[self.undoManager prepareWithInvocationTarget:self] removeObjectFromAttendeeListAtIndex:(NSUInteger) index];
undoManager.actionName = @"Insert Person";
}
-(void) removeObjectFromAttendeeListAtIndex:(NSUInteger)index {
Person *deletedPerson = [self.attendeeList objectAtIndex:index];
// housecleaning before removing the person
[self stopObservingPerson:(Person *)deletedPerson];
// remove the object/person
[self.attendeeList removeObjectAtIndex:index];
// configure the undo
[[self.undoManager prepareWithInvocationTarget:self] insertObject:(id *)deletedPerson inAttendeeListAtIndex:index];
// Notify the undoManager
undoManager.actionName = @"Remove Person";
}
Note: Mon KVO pour Person.name et Person.rate fonctionnent. Je les vois appelés dans le débogueur. De même, insertObject: inAttendeeListAtIndex et removeObjectFromAttendeeListAtIndex: sont également appelés. – vesselhead
On dirait que mon undoManager est null et c'est pourquoi il ne fonctionne pas. Pourquoi serait-ce nul? – vesselhead