语境
我有一个 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;
问题
尽管选定的行总是准确的,但从代表单元格中获取值却不是。看起来最初返回的值是正确的,但是即使选择的索引仍然正确,选择其他行也会从下一行返回数据。我还观察到它从视图中的几行返回值。
更新
在进一步测试之后,第一次应用过滤器似乎可以工作,但是通过不同的字符串过滤会保留第一个选定单元格的单元格值以应对特定的不稳定。
IE:
- 加载窗口并选择 6 个项目
- 取消选择第 6 项并警告用户
- 应用过滤器
- 选择新的第 6 项
- 取消选择第 6 项并警告用户
- 在同一过滤器中选择不同的第 6 项
- 取消选择第 6 项并警告用户
- 输入新过滤器
- 选择新的第 6 项
- 取消选择第 6 项并警告用户
- 从同一过滤器中选择新的第 6 项
- 所选索引正确,但所选行的值与之前的选择相同
- 用户反复警告,因为没有取消选择正确的条目,导致 6 个永久选中的条目。
但是,仍然存在返回以下行值而不是先前选择的项目的情况。
问题
我的问题是:
- 我是否以正确的方式为过滤列表获取选定的行?
- 即使列表已排序,如何根据所选行一致地检索第 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;