基于视图的 NSTableView 的目标操作数据源更新

Posted

技术标签:

【中文标题】基于视图的 NSTableView 的目标操作数据源更新【英文标题】:Target Action data source update for view based NSTableView 【发布时间】:2011-10-27 11:20:27 【问题描述】:

我有使用基于视图的表视图并且不想在数据源和表视图之间使用绑定的情况。这主要是因为我的 NSTableCellView 可以有多个子视图、复杂的验证和触发对其他对象中方法的调用。

我们有非常清晰的使用数据源更新 NSTableView 的路径:

tableView:viewForTableColumn:row:

但是,向后,即使用 NSTableView 中的更新更新数据源,我们没有任何基于单元格的表格视图的那种:

tableView:setObjectValue:forTableColumn:row:

建议使用目标操作模式。所以,我基本上有两个问题:

    如果我为一个特定视图或其子视图设置目标和操作,我如何获得正确的行和列信息以了解要在数据源中更新什么?

虽然我已经编辑或更改了一个子视图对象,但 NSTableView 中的 clickedRow 和 clickedColumn 是否应该起作用?

    如果操作将传递例如 NSTextField 作为参数,我如何通知目标(作为其他对象,而不是 NSTableView 实例)有关行和列?

我基本上可以通过子视图树来 clickedColumn 和 clickedRow (如果这两个属性是第一个问题的正确答案),但我发现这是非常不优雅的解决方案,并且预感有更好的方法....

提前谢谢....

【问题讨论】:

【参考方案1】:

NSTableCellView 有一个objectValue。大概你已经在设置它了,所以该动作可以使用[(NSTableCellView *)[sender superview] objectValue] 来找出它需要操作的对象。

我建议你也继承 NSTableCellView 并在那里实现操作。如果你需要访问模型的其他部分,你可以为你的视图控制器添加一个出口。

如果您确实需要行号,可以在您的内容数组上调用indexOfObject

【讨论】:

是的,我打算继承 NSTableCellView 并且我的操作方法很可能会在其他一些类中。所以,我假设类似 [[[(NSTableCellView *)[sender superview] objectValue] superview] clickedRow] 可以给我点击行的行位置和点击列的类似位置? 应该可以。为了使其更清晰,请为行号和列号提供自定义单元格属性,并在 tableView:viewForTableColumn:row: 中设置值。【参考方案2】:

两个 NSTableView 方法 rowForView 和 columnForView 应该可以解决问题。 您可以使用目标/操作方法的发送者调用它们,例如由 TableView 中的 NSButton 触发的方法(可以,将其放在子视图中的某个位置) 或者,您可以从委托方法实现中调用这些方法,例如来自 NSTextDelegate 的 textDidChange。这样您就可以轻松更新相应的 Array。 如果您不希望持续更新 textDidEndEditing 也可以完成这项工作。

- (void)textDidChange:(NSNotification *)notification

    NSTextView *tv = [notification object];
    int r = [tableView rowForView:tv];
    int c = [tableView columnForView:tv];
    NSLog(@"Row: %d Column: %d", r, c);
    // updating code here

【讨论】:

以上是关于基于视图的 NSTableView 的目标操作数据源更新的主要内容,如果未能解决你的问题,请参考以下文章

基于视图的 NSTableView 中的 NSPopupButton

正确调整基于视图的 NSTableView 上的行大小

基于视图的 NSTableView 中的自定义背景

OSX 基于视图的 NSTableView 字体更改

tableCellView 内的 NSButton:如何对基于视图的 NSTableView/NSArrayController 使用“动作调用”

为 NSTableView 单元格绘制带有边框和背景的文本