2011-11-13 3 views
0

회의가있는 문서가 있습니다. 회의를 초기화 할 때 문서의 실행 취소 관리자를 가리 키도록 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"; 

} 
+0

참고 : Person.name 및 Person.rate의 KVO가 작동 중입니다. 디버거에서 호출 된 것을 볼 수 있습니다. 마찬가지로 insertObject : inAttendeeListAtIndex 및 removeObjectFromAttendeeListAtIndex :도 호출됩니다. – vesselhead

+0

내 undoManager가 null 인 것처럼 보이므로 작동하지 않습니다. 왜 그것이 null이 될까요? – vesselhead

답변

0

나는 내 문제에 대한 답을 발견했다. 나는 두 가지 방법 중 하나로 회의를 초기화한다. 새로운 문서 및 보관 된 문서를 통해. 아카이브에서로드 할 때 undoManager를 할당하지 않아서 null이 아니며 아무 것도 happendi가되었습니다.