2011-11-13 21 views
0

私は会議があるドキュメントを持っています。 ミーティングを初期化するときに、ドキュメントのundoManagerを指すようにundoManagerを設定します。 同様に、私の会議には出席者(Personのリスト)があります。各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

注ませんでしたので、私はundoManagerを割り当てていませんでした。私はそれらがデバッガで呼び出されるのを見ます。同様に、insertObject:inAttendeeListAtIndexとremoveObjectFromAttendeeListAtIndex:も呼び出されています。 – vesselhead

+0

私のundoManagerがnullで、それが動作しない理由です。なぜそれがnullになるのでしょうか? – vesselhead

答えて

0

は、私は私の問題への答えを見つけました。私は2つの方法のうちの1つを初期化します。新しい文書とアーカイブされた文書。 Person.nameとPerson.rateが働いているため私のKVO:私はアーカイブからロードされたとき、それがnullだったと何もhappendi

関連する問題