【问题标题】:How can I consistently get the selected cell value from a filtered NSTableView?如何始终从过滤的 NSTableView 中获取选定的单元格值?
【发布时间】:2014-07-30 07:21:38
【问题描述】:

上下文

我有一个 2 列、基于单元的 NSTableView,由 NSArrayController 管理。

  • 第一列填充了复选框以指示该值是否已启用。
  • 第二列代表元素的名称。

视图链接到 NSSearchField,因此根据将搜索字符串与第 2 列中的字符串进行比较的谓词进行过滤。

当搜索字符串更改时,视图显示正确并按预期过滤。

要求

我只需要允许用户最多启用 5 行。为了实现这一点,我正在监视支持数组的更改并跟踪启用条目的数量。如果计数超过 5,则我会通过警报通知用户并通过获取选定的行索引然后在后备数组中禁用该索引来取消选择先前启用的条目。我在 [willChange.. ..didChange] KVO 块中执行此操作。

当视图未排序时,这可以按预期工作,但当因为所选行不再对应于数组中的适当索引时,显然会导致问题。

因此,如果视图被过滤(搜索字符串不为空),我使用以下代码获取所选单元格的字符串值。然后我遍历数组并禁用匹配字符串的条目。

NSInteger selectedRow = [_tv_TableView selectedRow];
NSTableColumn* column=  [_tv_TableView tableColumns][1];
NSCell* cell = [column dataCellForRow:row];
NSString* cellValue = (NSString*)[cell stringValue];
return cellValue;

问题

虽然选择的行总是准确的,但从代表单元格中获取值却不是。看起来最初返回的值是正确的,但是即使选择的索引仍然正确,选择其他行也会从下一行返回数据。我还观察到它从视图中的几行返回值。

更新

经过进一步测试,似乎第一次应用过滤器时它会起作用,但是通过不同的字符串过滤会保留第一个选定单元格的单元格值以应对特定的不稳定。

即:

  1. 加载窗口并选择 6 项
  2. 第 6 项已取消选择并警告用户
  3. 应用过滤器
  4. 选择新的第 6 项
  5. 第 6 项已取消选择并警告用户
  6. 在同一过滤器中选择不同的第 6 项
  7. 第 6 项已取消选择并警告用户
  8. 输入新过滤器
  9. 选择新的第 6 项
  10. 第 6 项已取消选择并警告用户
  11. 从同一过滤器中选择新的第 6 项
  12. 所选索引正确,但所选行的值与之前的选择相同
  13. 用户反复警告,因为没有取消选择正确的条目,导致 6 个永久选中的条目。

但是,仍然存在返回以下行值而不是先前选择的项的情况。

问题

我的问题是:

  1. 我是否以正确的方式为过滤列表获取选定行?
  2. 即使列表已排序,我如何才能始终如一地根据所选行检索第 2 列的字符串值?

感谢您的宝贵时间。

解决方案

我通过更改获取单元格的代码解决了这个问题:

NSInteger selectedRow = [_tv_TableView selectedRow];
NSTableColumn* column=  [_tv_TableView tableColumns][1];
NSCell* cell = [column dataCellForRow:row];
NSString* cellValue = (NSString*)[cell stringValue];
return cellValue;

收件人:

NSCell* cell = [_tv_TableView preparedCellAtColumn:1 row:row];
NSString* cellValue = (NSString*)[cell stringValue];
return cellValue;

【问题讨论】:

    标签: objective-c cocoa nstableview nscell nssearchfield


    【解决方案1】:

    简单的解决方案是将表的selectionIndexes 绑定绑定到数组控制器的同名属性。然后,您可以访问数组控制器的-selectedObjects 来查找,嗯,选定的对象。

    当您有来自表的行(或索引)时,无论它是否被选中,您都可以使用NSArrayController-arrangedObjects。这将始终对应于索引。

    细胞被重复使用。没有一个单元格与每个(行、列)位置相关联。每列都有一个单元格,但每次需要绘制或以其他方式操作一行时,都会为每一行重新配置它。这就是您需要 prepared 单元格的原因。也就是说,单元在概念上位于视图层(在模型-视图-控制器中)。你所做的应该在控制器和模型域中,所以你不应该咨询视图层(也不应该需要)。

    【讨论】:

      【解决方案2】:

      由于某种原因,在更改 NSSearchField 中的过滤器时,项目的内部表示没有更新。这是返回的值与 实际视图。

      我通过更改获取单元格的代码解决了这个问题:

      NSInteger selectedRow = [_tv_TableView selectedRow];
      NSTableColumn* column= [_tv_TableView tableColumns][1];
      NSCell* cell = [column dataCellForRow:row];
      NSString* cellValue = (NSString*)[cell stringValue];
      return cellValue;
      

      收件人:

      NSCell* cell = [_tv_TableView preparedCellAtColumn:1 row:row];
      NSString* cellValue = (NSString*)[cell stringValue];
      return cellValue;
      

      在此之前,我还尝试使用以下方法强制视图手动更新:

      [_tv_TableView reloadData];
      

      但这对结果没有影响。 我仍然有兴趣确切地知道为什么会发生这种情况。如果我知道了,我会 更新答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-07
        • 2012-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多