如何自动选择插入的项目和NSOutlineView&核心数据

时间:2011-04-22 18:30:16

标签: cocoa core-data selection cocoa-bindings nsoutlineview

我有NSTreeController绑定NSArrayController绑定到实体,树绑定到NSOutlineView。现在,当点击“添加”按钮时,我想向treeController添加一个新实体,选择实体,然后突出显示它以进行编辑。如果我调用[arrayController add],插入是异步的,我无法知道新对象是什么,因为大纲视图不会自动选择新行。所以我只能以编程方式插入新的Entity。因此addButtoncreateNewGroup上调用outlineViewController(见下文)。

同样,插入新实体似乎不是一个同步过程。我无法在NSOutlineView之后的下一行currentObject = [NSEntityDescription...中找到它。我在重新加载数据后尝试过。所以我留下观察数组控制器中的值变化。大多数时候,这种作品,但偶尔也没有。这是对这类事情的正确方法吗?

- (void) createNewGroup:(id)sender {
    NSInteger row = [myOutlineView selectedRow];
    if(row == -1) {
        [groupsController addObserver:self 
                           forKeyPath:IR_GROUPS_KEYPATH 
                              options:NSKeyValueObservingOptionInitial 
                              context:IR_GROUPS_CONTEXT];
        currentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" 
                                                      inManagedObjectContext:appDelegate.managedObjectContext];
        return;
    }
    if([myOutlineView levelForRow:row] != 0) return;
    [subGroupsController addObserver:self 
                          forKeyPath:IR_GROUPS_KEYPATH 
                             options:NSKeyValueObservingOptionInitial 
                             context:IR_SUBGROUPS_CONTEXT];
    NSManagedObject *parent = [[myOutlineView itemAtRow:row] representedObject];
    currentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" 
                                                            inManagedObjectContext:appDelegate.managedObjectContext];
    [currentObject setValue:parent forKey:@"parent"];
}

- (void) observeValueForKeyPath:(NSString *)keyPath 
                       ofObject:(id)object 
                         change:(NSDictionary *)change 
                        context:(void *)context {

    if([keyPath isEqualToString:IR_GROUPS_KEYPATH]) {
        if(currentObject == nil) return;
        [myOutlineView noteNumberOfRowsChanged];
        NSString *ctx = (NSString *) context;
        if([ctx isEqualToString:IR_GROUPS_CONTEXT]) {

            NSInteger length = [myOutlineView numberOfRows];
            NSInteger index;
            for(index = 0; index < length; index++) {
                id item = [myOutlineView itemAtRow:index];
                if(currentObject == [item representedObject]) {
                    // We found the new object:
                    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:index];
                    [myOutlineView selectRowIndexes:indices byExtendingSelection:NO];
                    [myOutlineView editColumn:0 row:index withEvent:nil select:YES];
                    currentObject = nil;
                    return;
                }
            }
            //[groupsController removeObserver:self forKeyPath:nil];

        } else if([ctx isEqualToString:IR_SUBGROUPS_CONTEXT]) {
            NSTreeNode *parent = [myOutlineView itemAtRow:[myOutlineView selectedRow]];
            [myOutlineView expandItem:parent];
            NSInteger length = [myOutlineView numberOfRows];
            NSInteger index;
            for(index = 0; index < length; index++) {
                id item = [myOutlineView itemAtRow:index];
                if(currentObject == [item representedObject]) {
                    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:index];
                    [myOutlineView selectRowIndexes:indices byExtendingSelection:NO];
                    [myOutlineView editColumn:0 row:index withEvent:nil select:YES];
                    currentObject = nil;
                    return;
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果使用(子类)NSTreeController为outlineView提供内容,则非常简单。您可以在代码或Interface Builder中创建一个按钮,并设置将目标绑定到insert:以添加元素,或remove:将其删除。在代码中它看起来像这样:

[aButton bind:NSTargetBinding 
     toObject:aController 
  withKeyPath:keyPathToTreeController
    options:[NSMutableDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSConditionallySetsEnabledBindingOption,
                             @"insert:", NSSelectorNameBindingOption,
                             nil]];

选择新对象由treeController处理。再次,在代码中:

[aTreeController setSelectsInsertedObjects:YES];

在IB中,它是您需要检查的复选框。哦,还有addChild:。让绑定发挥他们的魔力。