Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa NSUndoManager-撤消按钮未显示_Cocoa_Nsundomanager - Fatal编程技术网

Cocoa NSUndoManager-撤消按钮未显示

Cocoa NSUndoManager-撤消按钮未显示,cocoa,nsundomanager,Cocoa,Nsundomanager,我有一份文件要开会。 初始化会议时,我将undoManager设置为指向文档的undoManager。 同样,我的会议也有与会者(人员列表)。每个Person对象只是指向我会议的undoManager,而它又只是指向文档的指针 在我开始观察人员属性的键值之前,我对向会议添加和删除与会者的撤消一直有效 你知道我做错了什么吗?添加和删除与会者时,“撤消”按钮不会激活。同样,当我更改此人的姓名/费率时,撤消按钮不会显示 文件.m - (id)init { self = [super init]

我有一份文件要开会。 初始化会议时,我将undoManager设置为指向文档的undoManager。 同样,我的会议也有与会者(人员列表)。每个Person对象只是指向我会议的undoManager,而它又只是指向文档的指针

在我开始观察人员属性的键值之前,我对向会议添加和删除与会者的撤消一直有效

你知道我做错了什么吗?添加和删除与会者时,“撤消”按钮不会激活。同样,当我更改此人的姓名/费率时,撤消按钮不会显示

文件.m

- (id)init
{
    self = [super init];
    if (self) {
        self.meeting = [[Meeting alloc] init];
        self.meeting.undoManager = self.undoManager;
会议h---

会议

- (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";

}

我找到了问题的答案。我用两种方式之一初始化会议。新文档和归档文档。当我从存档加载时,我没有分配undoManager,因此它为空,什么也没有发生注意:我的Person.name和Person.rate的KVO正在工作。我看到它们在调试器中被调用。同样,insertObject:InAttendeeListIndex和RemoveObjectFromAttendeeListIndex:也被调用。看起来我的undoManager为null,这就是它不工作的原因。为什么它是空的?
- (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";

}