Как автоматически выбрать элемент, вставленный в NSOutlineView & Core Data - PullRequest
0 голосов
/ 22 апреля 2011

У меня есть 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 голос
/ 23 апреля 2011

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

...