【问题标题】:Update bound dictionary based on NSTextFieldCell's edited value根据 NSTextFieldCell 的编辑值更新绑定字典
【发布时间】:2009-06-04 21:54:50
【问题描述】:

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

绑定模型如下所示:

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

NSOutlineView 的 NSTableColumn 值 -> 树控制器:arrangedObjects: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];
}

【问题讨论】:

  • 代码在你的 NSTextField 子类中?
  • 是的,这是 NSTextFieldCell 子类的核心。

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


【解决方案1】:

我四处打听,这是有人给我的建议;看起来很合理。

在您的 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 推送更改。它应该适用于表格和大纲视图以及任意模型对象,无论是否有核心数据。

【讨论】:

    【解决方案2】:

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

    IIRC,您传递的 item 参数实际上是一个 NSTreeNode 实例,其代表对象属性将为您提供该行的 NSManagedObject 实例,因此您可以从中获取所需的任何信息。

    【讨论】:

    • outlineView:willDisplayCell:forTableColumn:item 用于读取值,但是如何更新表格单元格中的 isChecked 值呢?过去,我只是在我的 NSCell 子类中设置委托方法来处理单击某些内容后的更改并在我的控制器中实现它们。看来我可以/应该使用 KVC/KVO 以更清洁的方式做到这一点。也许我错了?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2021-09-04
    • 1970-01-01
    • 2012-01-18
    • 2021-08-15
    相关资源
    最近更新 更多