我的应用程序中有一个包含多个列的NSTableview
。当我单击一个列标题以使其按升序排序时,该列中具有nil值的行将按顶部排序,然后按升序排列非零值行。如果我在同一列上单击,则首先按降序显示非零值行,然后是零值行。
我想要做的是将零值行总是粘在底部。因此,首先应该呈现以递增或递减方式排序的非零值行,并且应将零值行保持在底部。如何才能以最佳方式完成?
在此上下文中进行排序 - 据我所知 - 由NSArrayController
的{{1}}完成。那么我应该将arrangedObject:
子类化并在NSArrayController
方法中使用自定义排序算法,还是有更好的方法来获得上述结果?
答案 0 :(得分:0)
我在自己的应用程序中通过创建NSSortDescriptor的自定义子类来实现它,这最终是NSArrayController用于执行其排序的。实现如下,它并不是非常复杂,但请注意它将空字符串与nil字符串一起排序到最后。遗憾的是,我无法(至少我知道)在Interface Builder中指定排序描述符子类,因此您必须在awakeFromNib方法中的相应NSTableColumn上手动创建一个并调用setSortDescriptorPrototype:
#define NULL_OBJECT(a) ((a) == nil || [(a) isEqual:[NSNull null]])
@interface MySortDescriptor : NSSortDescriptor {}
@end
@implementation MySortDescriptor
- (id)copyWithZone:(NSZone*)zone
{
return [[[self class] alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]];
}
- (id)reversedSortDescriptor
{
return [[[[self class] alloc] initWithKey:[self key] ascending:![self ascending] selector:[self selector]] autorelease];
}
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
{
if (NULL_OBJECT([object1 valueForKeyPath:[self key]]) ||
[[object1 valueForKeyPath:[self key]] length] == 0)
return ([self ascending] ? NSOrderedDescending : NSOrderedAscending);
if (NULL_OBJECT([object2 valueForKeyPath:[self key]]) ||
[[object2 valueForKeyPath:[self key]] length] == 0)
return ([self ascending] ? NSOrderedAscending : NSOrderedDescending);
return [super compareObject:object1 toObject:object2];
}
@end
答案 1 :(得分:0)
非常感谢。正如我上面提到的,我总是希望将nil-values排序到底部我使用compareObject的代码:以下面的方式。
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2 {
if (NULL_OBJECT([object1 valueForKeyPath:[self key]]) && NULL_OBJECT([object2 valueForKeyPath:[self key]]))
return NSOrderedSame;
if (NULL_OBJECT([object1 valueForKeyPath:[self key]]))
return NSOrderedDescending;
if (NULL_OBJECT([object2 valueForKeyPath:[self key]]))
return NSOrderedAscending;
return [super compareObject:object1 toObject:object2];
}