如何自动选择插入到 NSOutlineView & Core Data 中的项目

Posted

技术标签:

【中文标题】如何自动选择插入到 NSOutlineView & Core Data 中的项目【英文标题】:How to automatically select an item inserted into and NSOutlineView & Core Data 【发布时间】:2011-04-22 18:30:15 【问题描述】:

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

同样,插入新实体似乎不是一个同步过程。我无法在currentObject = [NSEntityDescription... 之后的下一行的NSOutlineView 中找到它。我在重新加载数据后确实尝试过。所以我只剩下观察数组控制器中的值变化了。这种工作,大部分时间,但偶尔不会。这是处理这类事情的正确方法吗?

- (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】:

如果你使用(一个子类)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:。让绑定发挥作用。

【讨论】:

谢谢,我试试看! 祝你好运。请注意,我从来没有说过使用 NSOutlineView(或 NSTreeController)很容易(嗨,Apple 开发人员技术支持——找到我最新的票了吗?),但这部分确实是。

以上是关于如何自动选择插入到 NSOutlineView & Core Data 中的项目的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa NSOutlineView 错误 - [NSCFTimer copyWithZone:]: 无法识别的选择器发送到实例

NSTreeController/NSOutlineView 失去选择

如何遍历我的 NSOutlineView 的所有项目?

如何有效地展平 NSOutlineView?

Cocoa NSOutlineView 取消选择先前的选择

从 NSOutlineView 中拖放