我正在加载一个我一无所知的CSV文件,除了第一行是列标题,可以是任何内容。列数也是未知的。我尝试在每个列中添加sortDescriptorPrototype,当我这样做时,我会在TableView中看到上/下箭头。
for(NSTableColumn * col in self.tableView.tableColumns){
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: col.title ascending: YES];
col.sortDescriptorPrototype = sortDescriptor;
}
每次单击sortDescriptorsDidChange列时都会调用:
- (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
[_data sortUsingDescriptors: [tableView sortDescriptors]];
[tableView reloadData];
}
_data是一个NSMutableArray,其中存储数据,第一行是标题名称。每一行都是另一个NSArray不幸的是我收到了这个错误:
2017-04-17 12:35:09.979142+0200 Table Tool[20954:2577488] [General] [<__NSCFString 0x610000474840> valueForUndefinedKey:]: this class is not key value coding-compliant for the key beds.
2017-04-17 12:35:09.982161+0200 Table Tool[20954:2577488] [General] (
0 CoreFoundation 0x00007fffb31a837b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fffc7f9c48d objc_exception_throw + 48
2 CoreFoundation 0x00007fffb31a82c9 -[NSException raise] + 9
3 Foundation 0x00007fffb4c83e5e -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
4 Foundation 0x00007fffb4b55d9c -[NSObject(NSKeyValueCoding) valueForKey:] + 283
5 Foundation 0x00007fffb4b59aac -[NSArray(NSKeyValueCoding) valueForKey:] + 467
6 Foundation 0x00007fffb4b55b79 -[NSArray(NSKeyValueCoding) valueForKeyPath:] + 448
7 Foundation 0x00007fffb4b7cc9f _sortedObjectsUsingDescriptors + 371
8 Foundation 0x00007fffb4be94f7 -[NSMutableArray(NSKeyValueSorting) sortUsingDescriptors:] + 468
9 Table Tool 0x00000001000051d8 -[Document tableView:sortDescriptorsDidChange:] + 184
10 AppKit 0x00007fffb0f05425 -[NSTableView setSortDescriptors:] + 260
11 AppKit 0x00007fffb13c9fbc -[NSTableView _changeSortDescriptorsForClickOnColumn:] + 480
显然我已经阅读了很多关于这个主题的内容,但是所有的例子都假设您在设计时知道了列名。我对 ObS-C 或 Swift 中 NSSortDescriptor 和 sortUsingDescriptors 的解决方案感兴趣,有些解释在sortDescriptorPrototype上以及为什么首先需要它,因为当我点击列时sortDescriptor会发生变化。我可以使用KVC中的任何东西作为分类键,例如&#34; self&#34; (有... valueForKeyPath:@&#34; @ sum.self&#34; ...)?
一些有用的链接:
https://www.raywenderlich.com/143828/macos-nstableview-tutorial
答案 0 :(得分:0)
这是一种完全愚蠢的解决方法,部分有效: 首先,我使用此方法提取列索引:
-(NSUInteger)getColumnIndexFromTableViewSortDescriptor {
for(NSUInteger i = 0; i < _maxColumnNumber; i++){
if(_tableView.tableColumns[i].title == _tableView.sortDescriptors[0].key){
return i;
}
}
assert(false && "Missing column name");
return 0;
}
然后我使用sortUsingComparator对数组进行就地排序。当然这必须是“错误的”。如果不使用sortDescriptors,那么使用sortDescriptors是完全愚蠢的,除了找出点击的列。我猜点击事件也可以解决这个问题吗?
-(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange: (NSArray *)oldDescriptors
{
NSUInteger idx = self.getColumnIndexFromTableViewSortDescriptor;
if(tableView.sortDescriptors[0].ascending){
[_data sortUsingComparator: ^(id obj1, id obj2) {
return [[obj2 objectAtIndex:idx] compare:[obj1 objectAtIndex:idx]];
}];
} else {
[_data sortUsingComparator: ^(id obj1, id obj2) {
return [[obj1 objectAtIndex:idx] compare:[obj2 objectAtIndex:idx]];
}];
}
[tableView reloadData];
}
现在我导入列中数据的CSV数据不一致,因此可能是NSNumber,后面跟着三个NSDecimalNumber和一些NSString。部分是我正在使用的数据和/或CSV解析器的问题(从网络上翻录,但我稍后会重写吸盘)。
因此,您最终可能会将NSDecimalNumber与NSString进行比较,这会产生如下错误:
unrecognized selector sent to instance
所以我继续愚蠢:
@interface NSDecimalNumber (CompareString)
-(NSComparisonResult)compare:(NSString *)string;
@end
@implementation NSDecimalNumber (CompareString)
-(NSComparisonResult)compare:(NSString *)string{
NSString *decimalString = self.stringValue;
return[decimalString compare:string options:NSCaseInsensitiveSearch];
}
现在,如果比较两个NSDecimalNumber,将调用上面的参数“string”NSDecimalNumber,即使“string”声明为NSString,也会导致“无法识别的选择器再次发送到实例”。