【问题标题】:Sorting nil-valued rows always to bottom in nstableview column在 nstableview 列中始终将 nil 值行排序到底部
【发布时间】:2010-06-29 22:37:24
【问题描述】:

我的应用程序中有一个NSTableview,其中包含几列。当我单击一个列标题以使其升序排序时,该列中具有零值的行将被排在顶部,然后是非零值行以升序排列。如果我重新单击同一列,首先将按降序显示非零值行,然后是零值行。

我想要做的是让 nil 值的行始终粘在底部。因此,首先应显示以升序或降序方式排序的非零值行,并且应将零值行保留在底部。如何以最好的方式做到这一点?

在这种情况下排序 - 据我了解 - 由 NSArrayControllerarrangedObject: 完成。那么我应该继承NSArrayController 并在arrangedObjects: 方法中使用自定义排序算法,还是有更好的方法来获得上述结果?

【问题讨论】:

    标签: objective-c cocoa sorting nstableview


    【解决方案1】:

    我通过创建 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
    

    【讨论】:

      【解决方案2】:

      非常感谢。正如我上面提到的,我总是希望将 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];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-27
        • 2013-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多