我有NSTreeController
绑定NSArrayController
绑定到实体,树绑定到NSOutlineView
。现在,当点击“添加”按钮时,我想向treeController
添加一个新实体,选择实体,然后突出显示它以进行编辑。如果我调用[arrayController add]
,插入是异步的,我无法知道新对象是什么,因为大纲视图不会自动选择新行。所以我只能以编程方式插入新的Entity。因此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;
}
}
}
}
}
答案 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:
。让绑定发挥他们的魔力。