#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 — уже выяснили мой последний запрос?), Но эта часть действительно проста.