【问题标题】:Changing NSTableCellView's objectValue in view-based NSOutlineView does not propagate to dataSource在基于视图的 NSOutlineView 中更改 NSTableCellView 的 objectValue 不会传播到 dataSource
【发布时间】:2011-11-07 10:36:48
【问题描述】:

我使用基于视图的NSOutlineView 来显示和选择科学应用程序的分层结构项目。

大纲列中的每一行代表一个项目,由一个项目特定的图标(在图片中都一样)、一个显示项目是否被选中的复选框以及项目的名称表示。我需要图标、复选框和名称出现在同一个单元格中,因此我使用基于视图的NSOutlineView

我已经实现了NSOutlineViewDataSource 协议来为大纲视图提供数据。

方法outlineView:objectValueForTableColumn:byItem: 提供了一个自定义对象,该对象具有BOOL selectedNSString *name 属性。

我在 IB 中的自定义表格单元格视图组成如下:

我将复选框值绑定到objectValue.selected,将标签值绑定到objectValue.name

正如我所希望的,大纲视图很好地显示了 objectValue 提供的名称和选择状态。

但是,如果我更改复选框的状态,则不会在我的 dataSource 中触发 NSOutlineViewDataSource 协议中定义的方法 outlineView:setObjectValue:forTableColumn:byItem: 以提供新更改的对象值。请注意,如果我不为单元格使用自定义视图,则此方法有效。

我通过将 NSLog 语句插入作为objectValue 传递的对象的setSelected 方法来检查单击复选框时表格单元格视图的objectValue.selected 是否实际发生更改。 selected 成员正确更改状态。

如何将objectValue 的更改传播回我的数据源模型?我已经检查了 NSOutlineView 的委托方法,但找不到一种方法来表示单元格视图的 objectValue 已被我的复选框更改(即单元格视图已“结束编辑”)。我还缺少其他一些基本点吗?

【问题讨论】:

  • 我注意到您正在使用数据源方法,而且您使用了“绑定”这个词。您在使用 Cocoa 绑定吗?如果是这样,您如何将复选框绑定到该对象?
  • 另外,outlineView:objectValueForTableColumn:byItem: 返回一个指向您的模型对象的指针是否正确?我建议检查是否正在调用 -copyWithZone:。如果是这样,则视图正在创建模型对象的第二个实例,这可能有助于解释为什么对复选框的更改不会传播回模型对象的原始实例。
  • 你发现了吗?我也遇到了同样的问题。

标签: objective-c cocoa osx-lion nstableview nsoutlineview


【解决方案1】:

setObjectValue 不适用于基于视图的:

来自标题::

/* View Based OutlineView: This method is not applicable.
 */
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;

【讨论】:

    【解决方案2】:

    我能够通过创建NSTableCellView 的子类,使其成为包含的NXTextField 的代表,并使用编辑后的值来更新NSTableCellView 的对象值来解决这个问题。

    class CategoryNameTableViewCell : NSTableCellView, NSTextFieldDelegate {
    
        func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
            guard var category = self.objectValue as! Category? else {
                Swift.print("Tried to edit category cell with no object!")
                return false
            }
            category.name = control.stringValue
            category.saveChanges()
            return true
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      相关资源
      最近更新 更多