根据NSTextFieldCell的编辑值更新绑定字典

时间:2009-06-04 21:54:50

标签: cocoa core-data cocoa-bindings key-value-coding

我正在努力将一些古代代码(10.2时代)从基于NSCoding / plist的归档移植到使用Core Data。我有一个带有自定义NSTextFieldCell的NSOutlineView。大纲视图绑定到NSTreeController以提供数据。

绑定模型如下所示:

NSTreeController: 托管对象上下文 - > Controller.managedObjectContext

NSOutlineView的NSTableColumn 价值 - >树控制器:arrangeObjects:itemDictionary

NSOutlineView有一个自定义的NSTextFieldCell子类,它在文本字段旁边添加一个图像,因此我将NSManagedObject的值作为名为itemDictionary的NSMutableDictionary传递给它,因此我可以拉取并设置标题和isChecked键值。

我遇到的问题是更新文本字段的值并将更改后的值传递回我的托管对象实例。用户双击标题值并对其进行编辑后,会将其传递给-(id)objectValue,但我不确定将更新传播到NSManagedObject实例的下一步是什么。到目前为止,我在NSTextFieldCell子类中读取和设置值的代码如下:

- (void)setStringValue:(NSString *)aString {
  [super setObjectValue:aString];
}

- (void)setObjectValue:(id <NSCopying>)anObject {  
  id cellValues = anObject;

  [super setObjectValue:[cellValues valueForKey:@"title"]];
  [self setCheckState:[[cellValues valueForKey:@"isChecked"] integerValue]];
}

- (id)objectValue {
  return [super objectValue];
}

2 个答案:

答案 0 :(得分:3)

我四处询问,这是有人给我的推荐;看起来很合理。

在NSCell子类中,在设置新值时,事件循环调用的任何方法都可以执行以下操作:

- (void)whateverMethodInCellSubclassIsTriggeredByEventLoop:(id)value {
    NSTableView *tableView = [self controlView];
    NSTableColumn *column = [[tableView tableColumns] objectAtIndex:[tableView editedColumn]];
    NSInteger rowIndex = [tableView editedRow];
    NSDictionary *bindingInfo = [column infoForBinding:NSValueBinding];
    id modelObject = nil;

    if ([controlView isKindOfClass:[NSOutlineView class]]) {
        NSTreeNode *item = [outlineView itemAtRow:rowIndex];
        modelObject = [item representedObject];
    } else if ([controlView isKindOfClass:[NSTableView class]]) {
        NSArrayController *controller = [bindingInfo objectForKey:NSObservedObjectKey];
        modelObject = [[controller arrangedObjects] objectAtIndex:rowIndex];
    }

    [modelObject setValue:value forKeyPath:[bindingInfo objectForKey:NSObservedKeyPathKey]];
}

这是一个相当通用的代码,它利用表列上可用的绑定信息来获取应该推送更改的模型对象和关键路径,并使用通用KVC来推送更改。它应该适用于表视图和大纲视图以及任意模型对象,核心数据与否。

答案 1 :(得分:0)

我可能会以不同的方式处理这个问题,方法是实现outlineView:willDisplayCell:forTableColumn:item:委托方法,并在那里设置单元格的isChecked属性,而不是在单元格子类中。然后,您只需将该列直接绑定到arrangeObjects.title,因此默认编辑机制将负责在托管对象实例上设置属性。

IIRC,您传递的item参数实际上是一个NSTreeNode实例,其representObject属性将为您提供该行的NSManagedObject实例,因此您可以通过这种方式获取所需的任何信息。