Как автоматически выбрать элемент, вставленный в и NSOutlineView

#cocoa #core-data #selection #cocoa-bindings #nsoutlineview

#cocoa #core-данные #выбор #cocoa-привязки #nsoutlineview

Вопрос:

У меня есть NSTreeController привязанный NSArrayController объект, а дерево привязано к NSOutlineView . Теперь, когда нажата кнопка «Добавить», я хотел бы добавить новый объект в treeController , выбрать объект и выделить его для редактирования. Если я вызываю [arrayController add] , вставка выполняется асинхронно, и у меня нет способа узнать, что это за новый объект, поскольку представление структуры не выбирает новые строки автоматически. Итак, я остаюсь с программной вставкой нового объекта. Поэтому addButton вызывает createNewGroup 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. Пожалуйста, отметьте свой вопрос как ответ, если он есть.

Ответ №1:

Если вы используете (подкласс) NSTreeController для предоставления содержимого для вашего outlineView, это очень просто. Вы создаете кнопку либо в code, либо в 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: . Позвольте привязкам творить свое волшебство.

Комментарии:

1. Удачи. Имейте в виду, я никогда не говорил, что использовать NSOutlineView (или NSTreeController) легко (привет, техническая поддержка разработчиков Apple — уже выяснили мой последний запрос?), Но эта часть действительно проста.