회의가있는 문서가 있습니다. 회의를 초기화 할 때 문서의 실행 취소 관리자를 가리 키도록 undoManager를 설정합니다. 마찬가지로, 회의에는 참석자 (사람 목록)가 있습니다. 각 Person 객체는 단순히 내 회의 undoManager를 가리키며, 이는 다시 Document에 대한 포인터입니다.NSUndoManager - 실행 취소 버튼이 표시되지 않습니다.
사람의 속성에 대한 키 값을 관찰하기 전까지 회의 참석자 추가 및 제거에 대한 실행 취소가 작동했습니다.
내가 뭘 잘못하고 있는지에 대한 아이디어가 있습니까? 참석자를 추가 및 제거하면 실행 취소 단추가 활성화되지 않습니다. 마찬가지로 사람 이름/비율을 변경하면 실행 취소 단추가 표시되지 않습니다.
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";
}
참고 : Person.name 및 Person.rate의 KVO가 작동 중입니다. 디버거에서 호출 된 것을 볼 수 있습니다. 마찬가지로 insertObject : inAttendeeListAtIndex 및 removeObjectFromAttendeeListAtIndex :도 호출됩니다. – vesselhead
내 undoManager가 null 인 것처럼 보이므로 작동하지 않습니다. 왜 그것이 null이 될까요? – vesselhead